单向链表-增加、删除、修改、查找、排序、反转-C语言-数据结构与算法

1-插入节点
2-删除节点
3-修改节点
4-查找节点
5-冒泡排序
6-选择排序
7-插入排序
8-快速排序(递归实现)
9-快速排序(迭代实现)
10-归并排序(递归实现)
11-归并排序(迭代实现)
12-链表反转

//****************************************
//数据结构:单向链表
//算法:增删改查和反转和排序
//首次编辑时间:2020/05/15
//最后修改时间:2020/05/26
//****************************************
#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
	int data;
	struct node *next;
}node;

node* creat();//创建链表
void show();//打印显示链表
void insert();//插入节点
void delete();//删除节点
void change();//修改节点
void search();//查找节点
void swap_value();//交换链表某两个节点的值
void swap_node();//交换链表某两个节点
void bubble_sort();//冒泡排序
void selection_sort();//选择排序
void insertion_sort();//插入排序
void quick_sort_recurrence();//快速排序(递归实现)
void quick_sort_iteration();//快速排序(迭代实现)
void merge_sort_recurrence();//归并排序(递归实现)
void merge_sort_iteration();//归并排序(迭代实现)
void reverse();//链表反转

int main()
{
	node* head = creat();
	while (1)
	{
		int action;
		printf("*****************************\n");
		printf("选择:\n");
		printf("0-结束退出 ");
		printf("1-插入节点\n");
		printf("2-删除节点 ");
		printf("3-修改节点\n");
		printf("4-查找节点 ");
		printf("5-冒泡排序\n");
		printf("6-选择排序 ");
		printf("7-插入排序\n");
		printf("8-快速排序(递归实现)\n");
		printf("9-快速排序(迭代实现)\n");
		printf("10-归并排序(递归实现)\n");
		printf("11-归并排序(迭代实现)\n");
		printf("12-链表反转\n");
		printf("-----------------------------\n");
		printf("原链表:");
		show(head);
		printf("-----------------------------\n");
		printf("输入选择序号:");
		scanf("%d", &action);
		printf("-----------------------------\n");
		switch (action)
		{
		case 0:return 0;
		case 1:insert(head);break;
		case 2:delete(head);break;
		case 3:change(head);break;
		case 4:search(head);break;
		case 5:bubble_sort(head);break;
		case 6:selection_sort(head);break;
		case 7:insertion_sort(head);break;
		case 8:quick_sort_recurrence(head, NULL);printf("新链表:");show(head);break;
		case 9:quick_sort_iteration(head, NULL);printf("新链表:");show(head);break;
		case 10:merge_sort_recurrence(head, NULL);printf("新链表:");show(head);break;
		case 11:merge_sort_iteration(head, NULL);printf("新链表:");show(head);break;
		case 12:reverse(head);printf("新链表:");show(head);break;
		default:printf("无效序号!");
		}
	}
}

node* creat()//创建链表
{
	node *head = (node*)malloc(sizeof(node)), *rear = head, *p;
	int i;
	for (i = 10;i > 0;i--)//创建链表时顺便增加10个节点
	{
		p = (node*)malloc(sizeof(node));
		p->data = i;
		p->next = NULL;
		rear->next = p;
		rear = p;	
	}
	return head;
}

void show(node *head)//打印显示链表
{
	node *s = head->next;
	while (s != NULL)
	{
		printf("->%d",s->data);
		s = s->next;
	}
	printf("\n");
}

void insert(node *head)//插入节点
{
	node *s, *p;
	int value, i, position;
	while (1)
	{
		printf("请输入插入位置(0为结束):");
		scanf("%d", &position);
		if (position == 0)
			return;
		printf("请输入插入数值:");
		scanf("%d", &value);
		p = (node*)malloc(sizeof(node));
		p->data = value;
		s = head;
		for (i = 2;i <= position;i++)
				s = s->next;
		p->next = s->next;
		s->next = p;
		printf("新链表:");
		show(head);
	}
}

void delete(node *head)//删除节点
{
	while (1)
	{
		int i, position;
		node *s,*d;
		printf("请输入删除位置(0为结束):");
		scanf("%d", &position);
		if (position == 0)
			return;
		s = head;
		for (i = 2;i <= position;i++)
			s = s->next;
		d = s->next;
		s->next = d->next;
		free(d);
		printf("新链表:");
		show(head);
	}
}

void change(node *head)//修改节点
{
	node *s;
	int value, i, position;
	while (1)
	{
		printf("请输入修改位置(0为结束):");
		scanf("%d", &position);
		if (position == 0)
			return;
		printf("修改为:");
		scanf("%d", &value);
		s = head;
		for (i = 1;i < position;i++)
		{
			s = s->next;
		}
		s->next->data = value;
		printf("新链表:");
		show(head);
	}
}

void search(node *head)//查询节点
{
	node *s;
	int value, i;
	while (1)
	{
		i = 1;
		printf("查询数值(-666为结束):");
		scanf("%d", &value);
		if (value == -666)
			return;
		s = head->next;
		while (s->data != value)
		{
			s = s->next;
			i++;
		}
		printf("该值在链表的第%d个\n",i);
	}
}

void swap_value(node *a, node *b)//交换链表某两个位置的值
{
	int temp;
	if (a == b)
		return;
	temp = a->data;
	a->data = b->data;
	b->data = temp;
}

void swap_node(node *head, node *a, node *b)//交换链表某两个节点
{
	node *a0 = NULL, *b0 = NULL;
	while ((head->next != NULL) && (a0 == NULL) || (b0 == NULL))
	{
		if (head->next == a)
			a0 = head;
		else if (head->next == b)
			b0 = head;
		head = head->next;
	}
	if ((a0 != b) && (b0 != a))
	{
		a0->next = a->next;
		b0->next = b->next;
		b->next = a0->next;
		a0->next = b;
		a->next = b0->next;
		b0->next = a;
	}
	else if(a0 == b)
	{
		b->next = a->next;
		a->next = b;
		b0->next = a;
	}
	else if(b0 == a)
	{
		a->next = b->next;
		b->next = a;
		a0->next = b;
	}
}

void bubble_sort(node *head)//冒泡排序
{
	node *d, *last = head->next;
	while (last->next != NULL)
		last = last->next;
	while (head->next != last)
	{
		d = head->next;
		while (1)
		{
			if (d->data > d->next->data)
				swap_value(d, d->next);
			if (d->next == last)
			{
				last = d;
				break;
			}
			d = d->next;
		}
	}
	printf("新链表:");
	show(head);
}

void selection_sort(node *head)//选择排序
{
	node *s = head->next, *d;
	while (s->next != NULL)
	{
		d = s;
		while (d != NULL)
		{
			if (s->data > d->data)
				swap_value(s, d);
			d = d->next;
		}
		s = s->next;
	}
	printf("新链表:");
	show(head);
}

void insertion_sort(node *head)//插入排序
{
	node *s = head->next, *h, *get;
	while(s != NULL && s->next != NULL)
	{
		get = s->next;
		h = head;
		while (h != s )
		{
			if (h->next->data > get->data)
			{
				s->next = get->next;
				get->next = h->next;
				h->next = get;
				break;
			}
			h = h->next;
		}
		if(h == s)
			s = s->next;
	}
	printf("新链表:");
	show(head);
}

void quick_sort_recurrence(node *left, node *right)//快速排序(递归实现)
{
	node *pivot = left->next, *d = left->next;
	if(left == right|| left->next == right || left->next->next == right)
		return;
	while(d != right)
	{
		if (d->data < pivot->data)
		{
			swap_value(pivot, d);
			pivot = pivot->next;
			if (pivot->next != d)
				swap_value(pivot, d);
		}
		d = d->next;
	}
	quick_sort_recurrence(left, pivot);
	quick_sort_recurrence(pivot, right);
}

void quick_sort_iteration(node *left, node *right)//快速排序(迭代实现)
{
	node *pivot, *d;
	int last = 0;//last用来记录未划分的区域个数。划分一次st长度++,进入划分一次st长度--,减到-1结束。
	struct st//用于保存每次划分的范围
	{
		node *left;
		node *right;
	}st[10];
	st[last].left = left;
	st[last].right = right;
	while (last > -1)
	{
		left = st[last].left;
		right = st[last--].right;
		if (left != right && left->next != right && left->next->next != right)
		{
			pivot = left->next;
			d = left->next;
			while (d != right)
			{
				if (d->data < pivot->data)
				{
					swap_value(pivot, d);
					pivot = pivot->next;
					if (pivot->next != d)
						swap_value(pivot, d);
				}
				d = d->next;
			}
			st[++last].left = left;
			st[last].right = pivot;
			st[++last].left = pivot;
			st[last].right = right;
		}
	}
}

void merge_sort_recurrence(node *left, node *right)//归并排序(递归实现)
{
	node *temp_head, *temp_rear, *temp_p, *slow = left, *fast = left, *p1, *p2, *p;


	if (left == right || left->next == right || left->next->next == right)
		return;
	while (fast != right && fast->next != right)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	merge_sort_recurrence(left, slow->next);
	merge_sort_recurrence(slow, right);
	p1 = left->next;
	p2 = slow->next;
	temp_head = (node*)malloc(sizeof(node));
	temp_head->next = NULL;
	temp_rear = temp_head;
	while (p1 != slow->next && p2 != right)
	{
		temp_p = (node*)malloc(sizeof(node));
		temp_p->next = NULL;
		temp_rear->next = temp_p;
		temp_rear = temp_p;
		if (p1->data < p2->data)
		{
			temp_p->data = p1->data;
			p1 = p1->next;
		}
		else
		{
			temp_p->data = p2->data;
			p2 = p2->next;
		}
	}
	while (p1 != slow->next)
	{
		temp_p = (node*)malloc(sizeof(node));
		temp_p->next = NULL;
		temp_rear->next = temp_p;
		temp_rear = temp_p;
		temp_p->data = p1->data;
		p1 = p1->next;
	}
	while (p2 != right)
	{
		temp_p = (node*)malloc(sizeof(node));
		temp_p->next = NULL;
		temp_rear->next = temp_p;
		temp_rear = temp_p;
		temp_p->data = p2->data;
		p2 = p2->next;
	}
	temp_p = temp_head->next;
	p = left->next;
	while (temp_p != NULL)
	{
		p->data = temp_p->data;
		temp_p = temp_p->next;
		free(temp_head->next);//释放临时链表空间
		temp_head->next = temp_p;
		p = p->next;
	}
	free(temp_head);//释放临时链表头节点空间	
}

void merge_sort_iteration(node *left, node *right)//归并排序(迭代实现)
{
	node *temp_head, *temp_rear, *temp_p, *mid, *p1, *p2, *p, *head = left;
	int i, j, c, n = 0;
	p = left;
	while (p->next != right)//计算链表长度
	{
		p = p->next;
		n++;
	}
	for (i = 1;i < n;i *= 2)
	{
		p2 = head->next;
		for (j = 1;(j + i) <= n;j += 2*i)
		{
			p1 = p2;
			mid = p1;
			left = p1;
			for (c = 1;c < i;c++)
				mid = mid->next;
			p2 = mid ->next;
			right = p2;
			for (c = 1;c < i;c++)
			{
				if (right->next == NULL)
					break;
				else
					right = right->next;
			}
			temp_head = (node*)malloc(sizeof(node));
			temp_head->next = NULL;
			temp_rear = temp_head;
			while (p1 != mid->next && p2 != right->next)
			{
				temp_p = (node*)malloc(sizeof(node));
				temp_p->next = NULL;
				temp_rear->next = temp_p;
				temp_rear = temp_p;
				if (p1->data < p2->data)
				{
					temp_p->data = p1->data;
					p1 = p1->next;
				}
				else
				{
					temp_p->data = p2->data;
					p2 = p2->next;
				}
			}
			while (p1 != mid->next)
			{
				temp_p = (node*)malloc(sizeof(node));
				temp_p->next = NULL;
				temp_rear->next = temp_p;
				temp_rear = temp_p;
				temp_p->data = p1->data;
				p1 = p1->next;
			}
			while (p2 != right->next)
			{
				temp_p = (node*)malloc(sizeof(node));
				temp_p->next = NULL;
				temp_rear->next = temp_p;
				temp_rear = temp_p;
				temp_p->data = p2->data;
				p2 = p2->next;
			}
			temp_p = temp_head->next;
			p = left;
			while (temp_p != NULL)
			{
				p->data = temp_p->data;
				temp_p = temp_p->next;
				free(temp_head->next);//释放临时链表空间
				temp_head->next = temp_p;
				p = p->next;
			}
			free(temp_head);//释放临时链表头节点空间
		}
	}
}

void reverse(node *head)//链表反转
{
	node *p = head, *tail = NULL;//tail为倒数第2个节点
	while (p->next->next != NULL)
	{
		tail = p;
		while (tail->next->next != NULL)
			tail = tail->next;
		tail->next->next = p->next;
		p->next = tail->next;
		tail->next = NULL;
		p = p ->next;
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值