栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构——排序(C语言)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构——排序(C语言)

目录

插入排序

一.直接插入排序

1.如何构建初始的有序序列

2.如何查找待插入记录的插入位置?

3.r[0]有两个作用:

直接插入排序代码:

二.希尔排序

1.应如何分割待排序记录?

2.子序列内如何进行直接插入排序?

希尔排序代码:

交换排序

一.起泡排序

1.如何记载一趟排序过程中交换的多个记录?

2.如何确定起泡排序的范围?

3.如何判别起泡排序的结束?

起泡排序代码:

二.快速排序

1.如何选择轴值?

2.如何实现一次划分

算法描述:

3.如何处理分割得到的两个待排序子序列?

4.如何判别快速排序的结束?

快速排序代码如下:

选择排序

一.简单选择排序

1.如何在无序区中选出关键字最小的记录?

2.如何确定最小记录的最终位置?

 简单选择排序代码:

堆排序

1.堆的定义

 归并排序

二路归并排序


插入排序

一.直接插入排序

1.如何构建初始的有序序列

将第1个记录看成是初始有序表,然后从第2个记录起依次插入到这个有序表中,直到将第n个记录插入。

2.如何查找待插入记录的插入位置?

在i-1个记录的有序区r[1] ~ r[i-1]中插入记录r[i],首先顺序查找r[i]的正确插入位置,然后将r[i]插入到相应位置。

3.r[0]有两个作用:

1. 进入循环之前暂存了r[i]的值,使得不致于因记录的后移而丢失r[i]的内容;
2. 在查找插入位置的循环中充当哨兵。

直接插入排序代码:
void insert(int r[],int n)//直接插入排序
{
	int i,j;
	for(i=2;i 

二.希尔排序

1.应如何分割待排序记录?

将相隔某个“增量”的记录组成一个子序列。
增量应如何取?
希尔最早提出的方法是d1=n/2,di+1=di/2。

2.子序列内如何进行直接插入排序?

在插入记录r[i]时,自r[i-d]起往前跳跃式(跳跃幅度为d)搜索待插入位置,并且r[0]只是暂存单元,不是哨兵。当搜索位置<0,表示插入位置已找到。
在搜索过程中,记录后移也是跳跃d个位置。
在整个序列中,前d个记录分别是d个子序列中的第一个记录,所以从第d+1个记录开始进行插入。

希尔排序代码:
void shellsort(int r[],int n)
{
	int d=0;
	for(d=n/2;d>=1;d=d/2)
	{
		for(i=d+1;i<=n;i++)
		{
			r[0]=r[i];
			j=i-d;
			while(j>0&&r[0] 

交换排序

一.起泡排序

1.如何记载一趟排序过程中交换的多个记录?

设变量exchange记载记录交换的位置,则一趟排序后,exchange记载的一定是这一趟排序中记录的最后一次交换的位置,且从此位置以后的所有记录均已经有序。

2.如何确定起泡排序的范围?

设bound位置的记录是无序区的最后一个记录,则每趟起泡排序的范围是r[1] ~ r[bound]。
在一趟排序后,从exchange位置之后的记录一定是有序的,所以bound=exchange。

3.如何判别起泡排序的结束?

在每一趟起泡排序之前,令exchange的初值为0,在以后的排序过程中,只要有记录交换,exchange的值就会大于0。这样,在一趟比较完毕,就可以通过exchange的值是否为0来判别是否有记录交换,从而判别整个起泡排序的结束。

起泡排序代码:
void BubbleSort(int r[ ], int n)
{	
    exchange=n; 	
    while (exchange) 
    {
        bound=exchange; 
        exchange=0;  
        for (j=1; jr[j+1]) {
                r[j]←→r[j+1];
	      exchange=j; 
            }
     }
 }

二.快速排序

1.如何选择轴值?

选择轴值的方法:
1.使用第一个记录的关键字;
2.选取序列中间记录的关键字;
3.比较序列中第一个记录、最后一个记录和中间记录的关键字,取关键字居中的作为轴值并调换到第一个记录的位置;
4.随机选取轴值。

选取不同轴值的后果:
决定两个子序列的长度,子序列的长度最好相等。

2.如何实现一次划分

设待划分的序列是r[s] ~ r[t],设参数i,j分别指向子序列左、右两端的下标s和t,令r[s]为轴值,
(1)j从后向前扫描,直到r[j] (2)i从前向后扫描,直到r[i]>r[j],将r[i]移动到r[j]的位置,使关键字大(同轴值比较)的记录移动到后面去;
(3)重复上述过程,直到i=j。

算法描述:
int Partition(int r[ ], int first, int end)
{	
    i=first; j=end;         //初始化
    while (i 

3.如何处理分割得到的两个待排序子序列?

解决方法:
对分割得到的两个子序列递归地执行快速排序。

4.如何判别快速排序的结束?

若待排序列中只有一个记录,显然已有序,否则进行一次划分后,再分别对分割所得的两个子序列进行快速排序(即递归处理)。

快速排序代码如下:
void QuickSort (int  r[ ], int first, int end )
{//在序列 first~end中递归地进行快速排序
    if (first < end) {					
          pivotpos = Partition (r, first, end );    
          QuickSort (r, first, pivotpos-1);
          QuickSort (r, pivotpos+1, end );
   }
}

选择排序

一.简单选择排序

1.如何在无序区中选出关键字最小的记录?

设置一个整型变量index,用于记录在一趟比较的过程中关键字最小的记录位置。

2.如何确定最小记录的最终位置?

第i趟简单选择排序的待排序区间是r[i] ~ r[n],则r[i]是无序区第一个记录,所以,将index所记载的关键字最小的记录与r[i]交换。

 简单选择排序代码:
void  selectSort ( int  r[ ], int n)
{   
    for ( i=1; ir[index]; 	 
    }
} 

堆排序

1.堆的定义

堆是具有下列性质的完全二叉树:每个结点的值都小于或等于其左右孩子结点的值(称为小根堆),或每个结点的值都大于或等于其左右孩子结点的值(称为大根堆)。

void  HeapSort ( int  r[], int n)
{
    for (i=n/2; i>=1; i--)      //初建堆
       sift(r, i, n) ;     
    for (i=1; i 

 归并排序

二路归并排序

将一个具有n个待排序记录的序列看成是n个长度为1的有序序列,然后进行两两归并,得到n/2个长度为2的有序序列,再进行两两归并,得到n/4个长度为4的有序序列,……,直至得到一个长度为n的有序序列为止。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/968808.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号