链表排序(交换节点)


链表头结点意义

带头结点的链表
头结点无实际数据,非必需,主要是为了操作的统一与方便而设立的
有头结点后,在第一个数据节点前插入、删除、修改的操作与对其它结点的操作统一了
基于带头结点的链表有了以下排序

链表初始化

typedef struct a
{
    
    
	int num;
	struct a* next;
}s,*List;
List head=NULL;

void Bubble(List);
void Insert(List);

main()
{
    
    
	int b[10]={
    
    9,14,5,3,4,2,8,10,11,6};//默认10个元素
	//头结点初始化
	List temp = (List)malloc(sizeof(s));
	temp->num=0;
	temp->next=NULL;
	head=temp;
	
	int i;
	for(i=0;i<10;i++)
	{
    
    
		List a = (List)malloc(sizeof(s));
		a->num=b[i];
		a->next=NULL;
		temp->next=a;
		temp = temp->next;
	}
}

一、冒泡排序

比较相邻节点,选出未排序元素中的最大数,并放在末尾

void Bubble(List head)
{
    
    
    List pre,cur,next,end;//pre前一项 cur当前项 next后一项 end控制循环次数(优化冒泡)
	end=NULL;

	while(head->next!=end)
	{
    
    
		//初始化三个指针 ; 判断是否到达结束位置 ; 三个指针集体后移
		for(pre=head,cur=pre->next,next=cur->next;  next!=end;  pre=pre->next,cur=cur->next,next=next->next)
		{
    
    
			if(cur->num > next->num) //从小到大
			{
    
    
				pre->next=next;
				cur->next=next->next;
				next->next=cur;

				//此时next变前一项,cur变后一项  交换next cur
				List temp=cur; cur=next; next=temp;
			}
		}

		//一轮循环结束 最后一项已经排好 end提前一项 (冒泡原理)
		end = cur;
	}
}

二、插入排序

需要用两个指针对链表进行遍历,一个指针用于标记待插入的节点(外循环),另一个指针用于寻找插入位置(内循环)

void Insert(List head)
{
    
    
	List p1,p2,temp,prep1,prep2;

	for(p1=head->next->next,prep1=head->next;p1!=NULL;p1=p1->next,prep1=prep1->next)
	{
    
    
		temp=p1;   //保存待插入节点
		for(p2=head->next,prep2=head ; p2!=p1 ; p2=p2->next,prep2=prep2->next)
		{
    
    
			if(p2->num > p1->num)
			{
    
    
				p1=p1->next;
				prep1->next=temp->next; 
				prep2->next=temp;     //插入对应位置
				temp->next=p2;
				break;
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/S_aitama/article/details/104434202