首页 > 其他分享 >单链表的冒泡,选择和快速排序

单链表的冒泡,选择和快速排序

时间:2024-04-06 20:33:40浏览次数:32  
标签:head 单链 cur max next tail 冒泡 prev 排序

单链表的冒泡,选择和快速排序

选择排序

选择排序的原理是在每一趟遍历时找出所有数据中最小或者最大的那一个值,然后放到开头或者末尾,在链表里面也是同样的道理,在下面的代码当中,遍历了一遍链表之后,我们找出了最大的那个值,然后用头插法插入链表的开头,关键的地方是链表不能查找到上一个节点,所以我们需要用两个指针,一个保留最大值,一个保留最大值的上面一个节点。

if(tail->next != max) {
			max_prev->next = max->next;
			max->next = tail->next;
			tail->next = max;
		}

这部分就是遍历了一遍链表之后,我们通过改链操作将目标值插入头节点之后,下一次开始遍历的时候就会跳过这个已查找过的值,对剩下的值继续操作,下面是完整的代码:

void SelectSort(struct node* head) {
	struct node *tail, *prev, *cur, *max, *max_prev;
	for(tail = head; tail && tail->next; tail = tail->next) {
		max = tail->next;
		for(cur = tail->next, prev = tail; cur != NULL; prev = cur, cur = cur->next) {
			if( cur->num > max->num) {
				max = cur;
				max_prev = prev;
			}
		}
		if(tail->next != max) {
			max_prev->next = max->next;
			max->next = tail->next;
			tail->next = max;
		}
	}
}

遍历一遍后找到最大值:

请添加图片描述

改链操作:

请添加图片描述

冒泡排序

冒泡排序的原理是每次遍历都能将最大值或者最小值沉底,以此来实现排序。

在数组里面,我们可以通过两两交换来实现沉底这个操作,但是在链表当中我们做不到,所以我们依然需要两个指针来进行操作,为了实现升序,我们这里用cur指向当前的节点,当cur指向的值比后一个节点指向的值要大的时候,我们需要交换这两个节点:

if((cur->num) > (cur->next->num)) {
				prev->next = cur->next;
				cur->next = cur->next->next;
				prev->next->next = cur;
				cur = prev->next;
			}

最后将最大值沉底之后,我们便不需要再对这个节点进行操作,需要将尾节点指针指向这个最大值,然后完整代码如下:

void BubbleSort(struct node* head) {
	struct node *tail, *prev, *cur;
	tail = NULL;
	while((head->next->next) != tail) {
		prev = head;
		cur = head->next;
		while((cur->next) != tail) {
			if((cur->num) > (cur->next->num)) {
				prev->next = cur->next;
				cur->next = cur->next->next;
				prev->next->next = cur;
				cur = prev->next;
			}
			cur = cur->next;
			prev = prev->next;
		}
		tail = cur;	//更新尾节点
	}
}

请添加图片描述

交换位置的改链操作:

请添加图片描述

完成后:

请添加图片描述

快速排序

快速排序使用分治的思想,遍历之前先设定一个基准值,然后遍历一次,将所有数分成两部分,一部分都是小于这个基准值,另一部分都是大于这个基准值,然后递归操作,这样子所有数都会归为有序

我们要做的有两件事情:

1.将所有的数分成两部分;

2.对左右两个部分递归排序;

显然,最关键的部分就是将数分成两个部分。对于数组我们可以定义左右两个指针,然后向中间靠,把数组分成两部分,但是因为链表的单向性,我们还是不能实现这个操作。这个时候我们就不考虑像数组那样直接交换目标值,我们可以把大于基准值的节点用头插法放到前面,这样子到了最后,我们的链表也能被分成两个部分

这里是关键代码;

if(hole->data < cur->data) {
			prev->next = cur->next;
			cur->next = head->next;
			head->next = cur;
		}
void QuickSort(struct Node* head, struct Node* tail) {
	if(head == NULL || head->next == tail || head->next->next == tail) {	//如果链表为空,或者只有一个节点就不用排序了
		return;
	}
	struct Node *cur, *prev, *hole;
	hole = head->next;	//设置基准值为第一个节点的值
	for(prev = hole, cur = hole->next; cur != NULL && cur != tail; cur = prev->next) {	//从基准值的下一个值开始遍历
		if(hole->data < cur->data) {	//若是大于基准值,就插入到头节点之后
			prev->next = cur->next;
			cur->next = head->next;
			head->next = cur;
		} else {
			prev = cur;	//要保持两个指针相邻,方便改链操作
		}
	}
	
	QuickSort(head,hole);
	QuickSort(hole,tail);
}

交换前:

请添加图片描述

改链:

请添加图片描述

完成后:

请添加图片描述

标签:head,单链,cur,max,next,tail,冒泡,prev,排序
From: https://blog.csdn.net/2303_80137294/article/details/137437190

相关文章

  • Python常用算法--排序算法【附源码】
    应用具体python案例方式展示各种排序的要点,特别是希尔排序、插入排序、选择排序、冒泡排序、堆排序、快速排序、归并排序七个具体的排序算法。一、希尔排序:解释:希尔排序(ShellSort)是一种插入排序的改进版本,也被称为缩小增量排序。希尔排序通过比较相距一定间隔的元素,将大间隔......
  • 排序查询
    排序查询语法:select查询列表(III)from表名(I)[where筛选条件](II)orderby排序列表[asc(升序,可省略)/desc(降序)](IV)特点:1、asc升序,可省略,desc降序,如不写默认升序2、orderby子句中支持单个字段、多个字段、表达式、函数、别名3、order......
  • 【数据结构与算法】:直接插入排序和希尔排序
    1.排序的概念及其意义1.1排序的概念所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。1.2排序的稳定性假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[......
  • AOV网络与拓扑排序
    活动网络可以用来描述生产计划、施工过程、生产流程、程序流程等工程中各子工程的安排问题。活动网络可分为两种:AOV网络和AOE网络。1.AOV网络与有向无环图 一般一个工程可以分成若干个子工程,这些子工程称为活动。完成了这些活动,整个工程就完成了。实际上,可以用有向图来表......
  • 结构体+排序——OpenJudge 1.10 07:合影效果
    描述小云和朋友们去爬香山,为美丽的景色所陶醉,想合影留念。如果他们站成一排,男生全部在左(从拍照者的角度),并按照从矮到高的顺序从左到右排,女生全部在右,并按照从高到矮的顺序从左到右排,请问他们合影的效果是什么样的(所有人的身高都不同)?输入第一行是人数n(2<=n<=40,且至少有1......
  • 十大排序算法的C++实现
    2024年4月5日排序算法一、稳定性的定义排序算法的稳定性是指排序过程中,相同元素的相对位置是否会发生变化。稳定的排序算法在排序过程中不会改变元素彼此的位置的相对次序,而不稳定的排序算法经常会改变这个次序。稳定性是一个特别重要的评估标准,排序算法的稳定性是一......
  • Java实现排序算法(1)
    七大常见排序算法直接插入排序希尔排序选择排序堆排序冒泡排序快速排序归并排序下文后三种排序算法(后三种排序算法详解)直接插入排序算法描述:定义两个下标(i和j).i从第二个元素开始,j从i前面开始,进行循环,途中定义一个temp,每次循环将i下标的元素放到temp中,与......
  • 逐点插入法【二叉查找(排序)树的插入算法】
    问题描述:利用逐点插入法建立序列{50,72,43,85,75,20,35,45,65,30}对应的二叉树排序后,查找元素30要进行多少次元素间的比较?首先我来解释以下什么是二叉查找树:二叉查找树是一棵空树,或者是具有如下性质的二叉树:(1)若它的左子树非空,则左子树中所有结点的值均小于根节点的值(2)若它的右......
  • 蓝桥杯备考随手记: 常用的三种排序算法(冒泡排序、插入排序、选择排序)
    1.冒泡排序(BubbleSort)冒泡排序是一种简单直观的排序算法,在待排序序列中不断地交换相邻两个元素的位置,通过多次遍历,将最大(或最小)的元素逐渐向右(或左)移动到正确的位置,直到整个序列有序。冒泡排序的基本思想如下:从序列的第一个元素开始,比较相邻两个元素的大小。如果前一个元......
  • 冒泡排序及qsort实现
    冒泡排序的核心思想就是:两两相邻的元素进行比较。假设有一个数组,它是:8 32 710 9107 4现在我们要通过两两对比的方式将其升序排列。我们要先将第一个和第二个对比,如果第一个数较大的话就交换位置。也就是说我们首先要将8和3对比然后交换位置,现在我们的数组就变为了3......