排序的链表实现

目录

朴素直接插入排序

冒泡的链表排序

完整的测试代码


朴素直接插入排序

本节将使用链表来实现直接插入排序。原理跟数组排序一致,就是细节上可能有差异。可能跟网上的有差异,仅供参考。

void Insertsort(List *&h){    //从小到大排序
	List *r,*s;		//前进结点 ,r为待排的首结点、已排的末结点。s为待交换节点
	int i=0;
	List *q,*p; 	//已排好的前进结点 
	r = h->next;    
	s = r->next;    //比较两个前进节点的大小
	int flag = 0;    //判断是否经过了交换
	while (r->next){
		i++;	//计算已排数量 
		if (s->data < r->data){		//若后一个比前一个小 则说明需要交换 
			q = h;	//从头开始比较 
			p = q->next;    //仅为了方便 也可以不写
			for (int j = 0; j < i; ++j){	//寻找交换的位置 
				if (s->data < p->data){	//判断插入位置,比当前最大的小那么就应该在这里					 
					r->next = s->next;    //先让已排的末结点链接到待排的首结点防止断链
                                         //关键句子 就是这个害我调了好久的bug
					s->next = q->next;    //接下来就是头插法
					q->next = s;
					flag = 1;    //另一个关键(bug)点,如果为1的话就说明r不需要前进
                                //让他继续与待排的首结点比较。否则r就可以前进
					break;    //减少循环次数,因为每次只需排一个
				}else{    //已排的前进结点
					q = q->next;    
					p = q->next;
				}
			}
		}
		if (flag == 1){    //这个不能放在上面这个if前 否则需要修改代码,不想调试了😭
                           //不加flag判断的话,r就会一直前进,错过结点,我记得就会死循环好像
			s = r->next;
			flag = 0;      //每次记得重置flag!
		}else{
			r = r->next;	
			s = r->next;	//比较r->next和r->next->next的data
			flag = 0;
		} 	
	}
} 

测试结果:

 、 、 

算法总结:这个基本完全就是按照数组中的排序规则进行排序的,没有经过优化,所以是“朴素”排序,另外链表注意不能断链!!,以及判断符号要及时重置


冒泡的链表排序

源自一个学长,加了一些注释

void BubbleSort(LNode *head){
	LNode *q,*p, *tail;
	int i = 0;
	tail = NULL;
	while (head->next->next != tail){
		p = head;
		q = head->next;
		while (q->next != tail){
			if (q->data > q->next->data){
				p->next = q->next;	
				q->next = q->next->next;
				p->next->next = q;	//上面三步就是交换了结点顺序 手画一下就清楚了 
				q = p->next;	//使其重新回到p后,为了后续前进操作保持一致
							   //如 1532 修改完后p在3上,但if结束后,两者都进一即p是3;q是5
							  //一开始我是想让p=p->next,直接让它是冒泡交换后的大值 但这样子会跳过好多结点 
			}
			p = p->next;
			q = q->next;
		} 
		tail = q;	//如果没有发生交换 则会退出循环 
	}
}

测试结果:

算法总结:q = q->next 是关键操作!!!详细在注释中,画画图理解一下


完整的测试代码

直接把里面的方法换一下即可

#include <stdio.h>
#define MAXSIZE 10

typedef struct Sqlist{
	int data[MAXSIZE];
	int length;
}Sqlist;

void createListR(LNode *&list, int S[], int n){			//尾插法 
	LNode *q,*p;
	list = (LNode*)malloc(sizeof(LNode));
	list->next = NULL;
	p = list;
	for (int i=0; i<n; i++){
		q = (LNode*)malloc(sizeof(LNode));
		q->data = S[i];
		p->next = q;
		p = p->next;
	} 
	p->next = NULL;
}
void createListF(LNode *&list, int S[], int n){			//头插法 
	LNode *r;
	list = (LNode*)malloc(sizeof(LNode));
	list->next = NULL;
	r = list;
	for (int i=0; i<n; ++i){
		r = (LNode*)malloc(sizeof(LNode));
		r->data = S[i];
		r->next = list->next;
		list->next = r;
	}
}

void showLinkList(LNode *list){
	LNode *s;
	s = list->next;
	while (s){
		printf("%d ", s->data);
		s = s->next;
	}
}
/*
    此处加入上述代码即可
*/
int main(){
	printf("相信自己!加油!");
	printf("\n");

	int a[10] = {1, 2, 99, 5, 4, 7, 8};
	LNode *A;
	createListR(A, a, 7);

	showLinkList(A); 
	printf("\n"); 
	BubbleSort(A);  //替换函数名
	showLinkList(A); 
	return 1;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值