严蔚敏数据结构习题第十章

本文汇总了各种排序算法(如快速排序、堆排序、直接插入排序等)的稳定性分析,包括稳定性定义及其实例,并介绍了中值记录、计数排序和奇偶交换排序等。此外,还涉及到了荷兰国旗问题和红旗问题的解决方案。适合学习者查阅和理解常见排序算法原理。
摘要由CSDN通过智能技术生成

第十章作业题目10.1 10.3 10.4 10.6 10.12 10.23 10.27 10.29 10.31 10.32 10.42 10.43。作业提交入口已开通,截止日期6月13日
https://wenku.baidu.com/view/4feba71baa956bec0975f46527d3240c8447a13d.html
https://blog.csdn.net/weixin_30699955/article/details/95661878
http://www.doc88.com/p-8059220558076.html
十大排序 https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

1

答案的 https://blog.csdn.net/qq_45846199/article/details/110442703
总:https://blog.csdn.net/xiaoxiaojie12321/article/details/81380834
https://www.runoob.com/w3cnote/radix-sort.html
快速排序 https://www.runoob.com/w3cnote/quick-sort.html
堆排序 https://www.cnblogs.com/chengxiao/p/6129630.html
在这里插入图片描述

3 算法稳定性

https://zhidao.baidu.com/question/525229984242427805.html
https://blog.csdn.net/qq_43152052/article/details/100078825
10.3❷试问在10.1题所列各种排序方法中,哪些是稳定的?哪些是不稳定的?并为每一种不稳定的排序方法举出一个不稳定的实例。
1.快速排序 比如序列为 5 3 3 4 3 8 9 10 11, 现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱
2.希尔排序 由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元 素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱
3.堆排序 堆的结构是节点i的孩子为2i和2i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n 的序列,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n /2-1, n/2-2, …1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没 有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。

4

在这里插入图片描述
(1)n-1
(2)1+2+…+n-1=
在这里插入图片描述

6 和29 奇偶交换

https://blog.csdn.net/shuiyixin/article/details/85252224
https://blog.csdn.net/lemon_tree12138/article/details/50605563
在这里插入图片描述
(1)当奇数交换和偶数交换都没有发生交换的时候就结束了
(2)2;n+2

#include <stdio.h>
#include <stdlib.h>

void Sort(int a[], int l)
{
	int temp;
	int i, j;
	int m = 1, n = 1;//如果奇排序过程中有元素交换,m为1,否则为0;如果偶排序过程中有元素交换,n为1,否则为0。
	//当mn同时为0时,说明奇偶都没有交换,这个时候说明数据有序。
	while (m || n)
	{
		for (i = 1; i < l - 1; i=i+2)
		{
			if (a[i] > a[i + 1])
			{
				temp = a[i];
				a[i] = a[i + 1];
				a[i + 1] = temp;
				m = 1;
			}
			else
				m = 0;
		}
		for (j = 0; j < l - 1; j = j + 2)
		{
			if (a[j] > a[j + 1])
			{
				temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
				n = 1;
			}
			else
				n = 0;
		}
	}
}

12 堆

在这里插入图片描述
(2)12,24,33,29,33,56,48, 65, 86, 70
(4) 05,28,20,23,40,38,29,61,35,76,56,100 交换3次

23 直接插入

http://www.aikanwk.com/tiku/1710.html
10.23❷试以L.r[k+1]作为监视哨改写教科书10.2.1节中给出的直接插入排序算法。其中,L.r[1…k]为待排序记录且k<MAXSIZE。

void InsertSort(SqList& L)
{
	int k = L.length;
	int i, j;
	for (i = k - 1; i > 0; i--)
	{
		if (L.r[i].key > L.r[i + 1].key)
		{
			L.r[k + 1] = L.r[i];  // 复制为监视哨
			for (j = i + 1; L.r[k + 1].key > L.r[j].key, j <= k; j++)//防止越界
				L.r[j - 1] = L.r[j];//记录往前移
		}
	}
 }

27 双向冒泡

https://wenku.baidu.com/view/4cd655b465ce0508763213b7.html
编写一个双向起泡的排序算法,即相邻两遍向相反方向起泡。

#include <stdio.h>
#include <stdlib.h>

void BiBubble(int r[], int n)
{
	int flag, i=0, j, temp;
	flag = 1;
	//printf("%d ", flag);
	while (flag == 1)
	{
		flag = 0;
		for(j=n-i-1;j>i;j--)//逆序冒泡,找最小
			if (r[j - 1] > r[j])
			{
				flag = 1;
				temp = r[j];
				r[j] = r[j - 1];
				r[j - 1] = temp;
			}
		for (j = i; j < n - i-1; j++)//正序冒泡,找最大
			if (r[j] > r[j + 1])
			{
				flag = 1;
				flag = 1;
				temp = r[j];
				r[j] = r[j + 1];
				r[j + 1] = temp;
			}
		i++;	 
	}
}

int main()
{
	int a[10];
	int i, j;
	for (i = 0, j = 10; i < 10; i++, j--)
		a[i] = j;
	BiBubble(a, 10);
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
}


29 奇偶交换排序

按10.6题所述编写奇偶交换排序的算法。

31

https://blog.csdn.net/happy_bigqiang/article/details/53364141?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#define max 10
typedef struct
{
	int key;
	//...
}RedType;

typedef struct
{
	RedType r[max];// r[0]用作哨兵单元
	int length;
}SqList;


void ti_31(SqList& L)
{
	int i = 0, j = L.length;
	while (i != j)
	{
		while (i < j && L.r[i].key < 0)
			i++;
		if (i < j)
			L.r[0] = L.r[i];
		while (i < j && L.r[j].key >= 0)
			j--;
		if (i < j)
		{
			L.r[i++] = L.r[j];
			L.r[j] = L.r[0];
		}
	}
}

int main()
{
	SqList l;
	l.length = 3;
	l.r[1].key = 3;
	l.r[2].key = -2;
	l.r[3].key = -9;
	ti_31(l);
	for (int i = 1; i < 4; i++)
		printf("%d ", l.r[i].key);
}

当关键字为正数的记录全部排在关键字为负数的记录之前时,需要移动的次数达到最大: n/2.

32 红旗问题

https://blog.csdn.net/qq_42191317/article/details/102779113?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
荷兰国旗问题:设有一个仅由红、白、蓝三种颜色的条块组成的条块序列。请编写一个时间复杂度为O(n)的算法,使得这些条块按红、白、蓝的顺序排好,即排成荷兰国旗图案。

#include <stdio.h>
#include <stdlib.h>
#define max 10
enum color{red,white,blue};
typedef struct
{
	int c[max];
	int length;
}FlagList;

void swap(int a[], int i, int j)
{
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}

void HFlag(FlagList& l)
{
	int i, j, k;
	int ll = l.length;
	for (i = 0, j = 0; j < ll;)
	{
		k = l.c[j];
		if (k == 0)
		{
			swap(l.c, i, j);
			i++;
			j++;
		}
		else if (k == 1)
			j++;
		else if (k == 3)
		{
			swap(l.c, j, ll-1);
			ll--;
		}
	}
}

int main()
{
	int a[10];
	int i, j;
	for (i = 0, j = 10; i < 10; i++, j--)
		a[i] = j;
	FlagList l;
	l.c[8];//不能赋初值,因为还有个key
}

42 中值记录

序列的“中值记录”指的是:如果将此序列排序后,它是第┌n/2┐个记录。试写一个求中值记录的算法。

#include <stdio.h>
#include <stdlib.h>
#define max 10
typedef struct
{
	int key;
	//...
}RedType;

typedef struct
{
	RedType r[max + 1];// r[0]闲置或用作哨兵单元
	int length;
}SqList;

int MidElement(SqList& L)
{
	int i, j, k, n;
	RedType temp;
	if (L.length == 0)
		return 0;
	for (i = 1; i < L.length; i++)//排序
	{
		k = i;
		temp = L.r[i];
		for(j=i+1;j<=L.length;j++)
			if (temp.key > L.r[j].key)
			{
				temp = L.r[j];
				k = j;
			}
		temp = L.r[i];
		L.r[i] = L.r[k];
		L.r[k] = temp;
	}
	if (L.length % 2 == 0)//找中值
		n = L.length / 2;
	else
		n = L.length / 2 + 1;
	return L.r[n].key;
}

43 ?

已知记录序列a[1…n]中的关键字各不相同,可按如下所述实现计数排序:另设数组c[1…n],对每个记录a[i],统计序列中关键字比它小的记录个数存于c[i],则c[i]=0的记录必为关键字最小的记录,然后依c[i]值的大小对a中记录进行重新排列,试编写算法实现上述排序方法。

#include <stdio.h>
#include <stdlib.h>
#define max 10
typedef struct
{
	int key;
	//...
}RedType;

typedef struct
{
	RedType r[max + 1];// r[0]闲置或用作哨兵单元
	int length;
}SqList;

void sort_43(SqList& L)
{
	int i, j;
	SqList t;
	int c[max];
	t = L;
	for (i = 1; i <= t.length; i++) //初始化c[]
		c[i] = 0;
	for (i = 1; i < t.length - 1; i++)//对每个记录统计比它小的关键字个数
	{
		for (j = i + 1; j <= t.length; j++)
		{
			if (t.r[i].key < t.r[j].key)
				c[j]++;
			else
				c[i]++;
		}
	}
	for (i = 1; i < t.length + 1; i++)//排序
		L.r[c[i] + 1] = t.r[i];
}

排序作业 选择题(每题2分,共22分)。 1.若表R在排序前已按键值递增顺序排列,则(   )算法的比较次数最少。 A.直接插入排序            B.快速排序     C.归并排序                D.选择排序 2.对各种内部排序方法来说,(   )。 A.快速排序时间性能最佳                             B.归并排序是稳定的排序方法 C.快速排序是一种选择排序                          D.堆排序所用的辅助空间比较大 3.  排序算法的稳定性是指(   )。 A.经过排序之后,能使值相同的数据保持原顺序中的相对位置不变。 B.经过排序之后,能使值相同的数据保持原顺序中的绝对位置不变。 C.排序算法的性能与被排序元素的数量关系不大 D.排序算法的性能与被排序元素的数量关系密切 4. 如下序列中,(   )序列是大顶堆。 A.  {4,5,3,2,1}               B.  {5,3,4,1,2}        C.  {1,2,3,4,5}               D.  {1,2,3,5,4} 5. 若将{3,2,5,4,1}排为升序,则实施快速排序一趟后的结果是(   )(其中,枢轴记录取首记录)。 A.  {1,2,3,4,5}                  B.  {1,2,4,5,3}        C.  {1,3,5,4,2}                  D.  {2,5,4,1,3} . 若将{1,2,3,4,5,6,7,9,8}排为升序,则(   )排序方法的“比较记录”次数最少。 A.  快速排序                   B.  简单选择排序     C.  直接插入排序               D.  冒泡排序 7. 若将{5,4,3,2,1}排为升序,则(   )排序方法的“移动记录”次数最多。 A.  快速排序                                B.  冒泡排序 C.  直接插入排序                       D.  简单选择排序 8. 用简单选择排序将顺序表{2,3,1 ,3′,2′}排为升序,实施排序1趟后结果是{1 ,3,2 ,3′,2′},则排序3趟后的结果是(   )。 A.  {1 ,2,3 ,3′,2′}                       B.  {1 ,2 ,2′,3 ,3′} C.  {1 ,2′,2 ,3 ,3′}                      D.  {1 ,2 ,2′,3′,3 } 9.下列排序算法中,(    )排序在某趟结束后不一定选出一个元素放到其最终的位置上。 A.选择             B.冒泡           C.归并           D.堆 10.下列排序算法中,稳定的排序算法是(  )。 A.堆排序                B.直接插入排序   C.快速排序              D.希尔排序 11.堆排序的时间复杂度是(    )。 A.O(n*n)                 B.O(n*log n)       C.O(n)                   D.O(log n) 填空题(每空4分,共4分)。 对n个元素进行归并排序,空间复杂度为         。 综合题(共24分)。 1. (共12分)有一组待排序的关键字如下: (54,38,96,23,15,72,60,45,83) 分别写出希尔排序(d=5)、快速排序、堆排序、归并排序第一趟升序排序后的结果(其中堆排序的第一趟指序列完成初始建堆、将堆顶元素置为最末位置后其余元素调整为堆的结果)(每个3分)。 希尔排序:   快速排序: 堆排序: 归并排序:  2. (共12分)已知数据序列为(12,5,9,20,6,31,24),对该项数据序列进行排序,分别写出直接插入排序、简单选择排序、快速排序、堆排序、二路归并排序及基数排序第一趟升序排序结果(其中堆排序的第一趟指序列完成初始建堆、将堆顶元素置为最末位置后其余元素调整为堆的结果)(每个2分)。 直接插入排序: 简单选择排序: 快速排序: 堆排序: 二路归并排序: 基数排序:    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值