排序 数据结构

时间:2024.5.8

#include"stdio.h"

#include"stdlib.h"

#define Max 100 //假设文件长度 typedef struct{ //定义记录类型 int key;

}RecType;

typedef RecType SeqList[Max+1];

int n;

//直接插入排序法

void InsertSort(SeqList R)

{

int i,j;

for(i=2;i<=n;i++)

if(R[i].key<R[i-1].key){

R[0]=R[i];j=i-1;

do {

R[j+1]=R[j]; j--;

}while(R[0].key<R[j].key);

R[j+1]=R[0]; }

}

typedef enum{FALSE,TRUE} Boolean;

//冒泡排序

void BubbleSort(SeqList R) { int i,j; Boolean exchange; for(i=1;i<n;i++) {

exchange=FALSE;

for(j=n-1;j>=i;j--)

if(R[j+1].key<R[j].key){ R[0]=R[j+1]; R[j+1]=R[j]; R[j]=R[0];

exchange=TRUE; }

if(! exchange)

return;

}

}

//一次划分函数

int Partition(SeqList R,int i,int j)

{

RecType pivot=R[i];

while(i<j) {

while(i<j &&R[j].key>=pivot.key) j--;

if(i<j)

R[i++]=R[j];

while(i<j &&R[i].key<=pivot.key) i++;

if(i<j)

R[j--]=R[i];

}

R[i]=pivot;

return i;

}

//快速排序

void QuickSort(SeqList R,int low,int high)

{

int pivotpos;

if(low<high) {

pivotpos=Partition(R,low,high);

QuickSort(R,low,pivotpos-1); QuickSort(R,pivotpos+1,high); }

}

//直接选择排序

void SelectSort(SeqList R)

{

int i,j,k;

for(i=1;i<n;i++){

k=i;

for(j=i+1;j<=n;j++)

if(R[j].key<R[k].key)

k=j;

if(k!=i) {

R[0]=R[i];R[i]=R[k];R[k]=R[0];

}

}

}

//大根堆调整函数

void Heapify(SeqList R,int low,int high)

{ // 将R[low..high]调整为大根堆,除R[low]外,其余结点均满足堆性质

int large;

RecType temp=R[low];

for(large=2*low; large<=high;large*=2){

//若large>high,表示R[low]是叶子,调整结束;否则令large指向R[low]的左孩子

if(large<high && R[large].key<R[large+1].key)

large++;

//现在R[large]是调整结点R[low]的左右孩子结点中关键字较大者

if(temp.key>=R[large].key) //temp始终对应R[low]

break;

R[low]=R[large];

low=large;

}

R[low]=temp;

}

//构造大根堆

void BuildHeap(SeqList R)

{ //将初始文件R[1..n]构造为堆

int i;

for(i=n/2;i>0;i--)

Heapify(R,i,n);

}

//堆排序

void HeapSort(SeqList R)

{ //对R[1..n]进行堆排序,不妨用R[0]做暂存单元

int i;

BuildHeap(R);

for(i=n;i>1;i--){

R[0]=R[1]; R[1]=R[i];R[i]=R[0];

Heapify(R,1,i-1);

}

}

//将两个有序的子序列R[low..m]和R[m+1..high]归并成有序的序列R[low..high] void Merge(SeqList R,int low,int m,int high)

{

int i=low,j=m+1,p=0;

RecType *R1;

R1=(RecType *)malloc((high-low+1)*sizeof(RecType));

while(i<=m && j<=high) //两个子序列非空时取其小者输出到R1[p]上 R1[p++]=(R[i].key<=R[j].key)? R[i++]:R[j++];

while(i<=m) //若第一个子序列非空,则复制剩余记录到R1

R1[p++]=R[i++];

while(j<=high) //若第二个子序列非空,则复制剩余记录到R1中

R1[p++]=R[j++];

for(p=0,i=low;i<=high;p++,i++)

R[i]=R1[p];

}

//对R[1..n]做一趟归并排序

void MergePass(SeqList R,int length)

{

int i;

for(i=1;i+2*length-1<=n;i=i+2*length)

Merge(R,i,i+length-1,i+2*length-1);

if(i+length-1<n) //尚有一个子序列,其中后一个长度小于length Merge(R,i,i+length-1,n);

//注意:若i≤n且i+length-1≥n时,则剩余一个子序列轮空,无须归并 }

//自底向上对R[1..n]做二路归并排序

void MergeSort(SeqList R)

{

int length;

for(length=1;length<n;length*=2)

MergePass(R,length);

}

//输入顺序表

void input_int(SeqList R)

{

int i;

printf("Please input num(int):");

scanf("%d",&n);

printf("Plase input %d integer:",n);

for(i=1;i<=n;i++)

scanf("%d",&R[i].key);

}

//输出顺序表

void output_int(SeqList R)

{

int i;

for(i=1;i<=n;i++)

printf("%4d",R[i].key);

}

//主函数

void main()

{

int i;

SeqList R;

input_int(R);

printf("\t******** Select **********\n");

printf("\t1: Insert Sort\n");

printf("\t2: Bubble Sort\n");

printf("\t3: Quick Sort\n");

printf("\t4: Straight Selection Sort\n");

printf("\t5: Heap Sort\n");

printf("\t6: Merge Sort\n");

printf("\t7: Exit\n");

printf("\t***************************\n");

scanf("%d",&i);

switch (i){

case 1: InsertSort(R); break; // 直接插入排序法

case 2: BubbleSort(R); break; //冒泡排序

case 3: QuickSort(R,1,n); break; //快速排序

case 4: SelectSort(R); break; //直接选择排序

case 5: HeapSort(R); break; //堆排序

case 6: MergeSort(R); break; //自底向上对R[1..n]做二路归并排序 case 7: exit(0);

}

printf("Sort reult:");

output_int(R);

}


第二篇:20xx年自学考试《数据结构》各章复习要点总结


20xx年自学考试《数据结构》各章复习要点总结(4) 龙耒为你整理:

第七章 图

图的逻辑结构特征就是其结点(顶点)的前趋和后继的个数都是没有限制的,即任意两个结点之间之间都可能相关。

图GraphG=(V,E),V是顶点的有穷非空集合,E是顶点偶对的有穷集。 有向图Digraph:每条边有方向;

无向图Undigraph:每条边没有方向;

有向完全图:具有n*(n-1)条边的有向图;

无向完全图:具有n*(n-1)/2条边的无向图;

有根图:有一个顶点有路径到达其它顶点的有向图;

简单路径:是经过顶点不同的路径;

简单回路:是开始和终端重合的简单路径;

网络:是带权的图。

图的存储结构:

·邻接矩阵表示法:用一个n阶方阵来表示图的结构是唯一的,适合稠密图。 ·无向图:邻接矩阵是对称的。

·有向图:行是出度,列是入度。

建立邻接矩阵算法的时间是O(n+n^2+e),其时间复杂度为O(n^2) ·邻接表表示法:用顶点表和邻接表构成不是唯一的,适合稀疏图。

·顶点表结构 vertex | firstedge,指针域存放邻接表头指针。 ·邻接表:用头指针确定。

·无向图称边表;

·有向图又分出边表和逆邻接表;

·邻接表结点结构为 adjvex | next,时间复杂度为O(n+e),空间复杂度为O(n+e)。

图的遍历:

·深度优先遍历:借助于邻接矩阵的列。使用栈保存已访问结点。 ·广度优先遍历:借助于邻接矩阵的行。使用队列保存已访问结点。 生成树的定义:若从图的某个顶点出发,可以系统地访问到图中所有顶点,则遍历时经过的边和图的所有顶点所构成的子图称作该图的生成树。 最小生成树:图的生成树不唯一,从不同的顶点出发可得到不同的生成树,把权值最小的生成树称为最小生成树(MST)。 构造最小生成树的算法: ·Prim算法的时间复杂度为O(n^2)与边数无关适于稠密图。

·Kruskal算法的时间复杂度为O(lge),主要取决于边数,较适合于稀疏图。 最短路径的算法:

·Dijkstra算法,时间复杂度为O(n^2)。

·类似于prim算法。

拓扑排序:是将有向无环图G中所有顶点排成一个线性序列,若∈E(G),则在线性序列u在v之前,这种线性序列称为拓扑序列。

拓扑排序也有两种方法: ·无前趋的顶点优先:每次输出一个无前趋的结点并删去此结点及其出边,最后得到的序列即拓扑序列。

·无后继的结点优先:每次输出一个无后继的结点并删去此结点及其入边,最后得到的序列是逆拓扑序列。

第八章 排序 记录中可用某一项来标识一个记录,则称为关键字项,该数据项的值称为关键字。

排序是使文件中的记录按关键字递增(或递减)次序排列起来。

·基本操作:比较关键字大小;改变指向记录的指针或移动记录。 ·存储结构:顺序结构、链表结构、索引结构。 经过排序后这些具有相同关键字的记录之间的相对次序保持不变,则称这种排序方法是稳定的,否则排序算法是不稳定的。

排序过程中不涉及数据的内、外存交换则称之为“内部排序”(内排序),反之,若存在数据的内外存交换,则称之为外排序。

内部排序方法可分五类:插入排序、选择排序、交换排序、归并排序和分配排序。

评价排序算法好坏的标准主要有两条:执行时间和所需的辅助空间,另外算法的复杂程序也是要考虑的一个因素。 插入排序: ·直接插入排序;

·逐个向前插入到合适位置;

·哨兵(监视哨)有两个作用;

·作为临变量存放R[i];

·是在查找循环中用来监视下标变量j是否越界;

·直接插入排序是就地的稳定排序。时间复杂度为O(n^2),比较次数为(n+2)(n-1)/2;移动次数为(n+4)(n-1)/2。

希尔排序:

·等间隔的数据比较并按要求顺序排列,最后间隔为1; ·希尔排序是就地的不稳定排序。时间复杂度为O(n^1.25),比较次数为(n^1.25);移动次数为(1.6n^1.25);

交换排序: 冒泡排序:

·自下向上确定最轻的一个。

·自上向下确定最重的一个。

·自下向上确定最轻的一个,后自上向下确定最重的一个。 ·冒泡排序是就地的稳定排序。时间复杂度为O(n^2),比较次数为n(n-1)/2;移动次数为3n(n-1)/2;

快速排序:

·以第一个元素为参考基准,设定、动两个指针,发生交换后指针交换位置,直到指针重合。重复直到排序完成。 ·快速排序是非就地的不稳定排序。时间复杂度为O(nlog2n),比较次数为n(n-1)/2。 选择排序:

·直接选择排序;

·选择最小的放在比较区前; ·直接选择排序就地的不稳定排序。时间复杂度为O(n^2)。比较次数为n(n-1)/2。

堆排序

·建堆:按层次将数据填入完全二叉树,从int(n/2)处向前逐个调整位置。 ·然后将树根与最后一个叶子交换值并断开与树的连接并重建堆,直到全断开。

·堆排序是就地不稳定的排序,时间复杂度为O(nlog2n),不适宜于记录数较少的文件。

归并排序:

·先两个一组排序,形成(n+1)/2组,再将两组并一组,直到剩下一组为止。 ·归并排序是非就地稳定排序,时间复杂度是O(nlog2n),

分配排序:

箱排序:

·按关键字的取值范围确定箱子数,按关键字投入箱子,链接所有非空箱。 ·箱排序的平均时间复杂度是线性的O(n)。

基数排序:

·从低位到高位依次对关键字进行箱排序。

·基数排序是非就稳定的排序,时间复杂度是O(d*n+d*rd)。

各种排序方法的比较和选择:

·待排序的记录数目n;n较大的要用时间复杂度为O(nlog2n)的排序方法; ·记录的大小(规模);记录大最好用链表作为存储结构,而快速排序和堆排序在链表上难于实现;

·关键字的结构及其初始状态;

·对稳定性的要求;

·语言工具的条件;

·存储结构;

·时间和辅助空间复杂度。

更多相关推荐:
数据结构排序超级总结

一插入排序InsertionSort1基本思想每次将一个待排序的数据元素插入到前面已经排好序的数列中的适当位置使数列依然有序直到待排序数据元素全部插入完为止2排序过程示例初始关键字493865977613274...

数据结构各种排序算法总结

数据结构各种排序算法总结计算机排序与人进行排序的不同计算机程序不能象人一样通览所有的数据只能根据计算机的quot比较quot原理在同一时间内对两个队员进行比较这是算法的一种quot短视quot1冒泡排序Bubb...

数据结构算法排序总结

数据结构与算法总结姓名:**学号:**班级:12计本(2)班这个学期在老师的带领下我们学习了数据结构与算法这门课程。在本次数据结构与算法的学习中最令我深刻的是关于几种排序算法的学习,所以在这里我想对我本学期所学…

数据结构中排序总结

排序总结排序方法平均时间最坏时间辅助存储简单排序O(n2)O(n2)O(1)快速排序O(nlogn)O(n2)O(logn)堆排序O(nlogn)O(nlogn)O(1)归并排序O(nlogn)O(nlogn)…

数据结构之排序总结(C语言)

数据结构实验课程之手工执行一下排序算法写出每一趟排序结束时的关键码状态includeltstdiohgtincludeltstdlibhgtdefinemaxsize20结构体的定义typedefstructi...

数据结构排序算法总结I

数据结构排序算法总结I考研复习到数据结构排序这章了这章的内容比较经典都是一些很好的算法将来很可能会用得到总结一下加深一下印象文章篇幅有点大请点击查看更多下面是跳转链接12312三选择排序1简单选择排序2堆排序五...

数据结构中常见的排序算法总结

几种常见排序算法的比较与实现1冒泡排序BubbleSort冒泡排序方法是最简单的排序方法这种方法的基本思想是将待排序的元素看作是竖着排列的气泡较小的元素比较轻从而要往上浮在冒泡排序算法中我们要对这个气泡序列处理...

数据结构排序

各种排序算法排序算法是一种基本并且常用的算法由于实际工作中处理的数量巨大所以排序算法对算法本身的速度要求很高而一般我们所谓的算法的性能主要是指算法的复杂度一般用O方法来表示在后面我将给出详细的说明对于排序的算法...

数据结构几种排序法

includeltstdiohgtincludeltstdlibhgttypedefintKeyTypeincludequot几种排序hquotvoidmainDataTypetest1043547119115...

数据结构-排序

第8章排序81排序的基本概念82插入排序83选择排序84交换排序本章主要知识点排序的基本概念和衡量排序算法优劣的标准其中衡量标准有算法的时间复杂度空间复杂度和稳定性直接插入排序希尔排序直接选择排序堆排序冒泡排序...

数据结构排序

第9章排序自测卷答案姓名班级一填空题每空1分共24分1大多数排序算法都有两个基本的操作针2在对一组记录543896231572604583进行直接插入排序时当把第7个记录60插入到有序表时为寻找插入位置至少需比...

数据结构实验报告——排序

1实验要求实验目的学习实现对比各种排序算法掌握各种排序算法的优劣以及各种算法使用的情况实验内容使用简单数组实现下面各种排序算法并进行比较排序算法1插入排序2希尔排序3冒泡排序4快速排序5简单选择排序6堆排序选作...

数据结构排序总结(27篇)