数据结构学习笔记 --- 排序(冒泡排序、快速排序)

原创 2012年03月24日 20:57:23

1. 引言 


本文主要讲解一些常见的排序算法。


2. 冒泡排序

冒泡排序是经过n-1趟子排序完成的,第i趟子排序从第1个数至第n-i个数,若第i个数比后一个数大(则升序,小则降序)则交换两数。

#include "ds.h"

#define 	N 		8

// 将a中整数序列重新排列成自小至大有序的整数序列(起泡排序)
void bubble_sort(int a[],int n)
{
	int i, j, t;
	Status change;
	for (i = n - 1, change = TRUE; i > 0 && change; --i)
	{
		change = FALSE;
		for (j = 0; j < i; j++)
		{
			if (a[j] > a[j+1])
			{
				t      = a[j];
				a[j]   = a[j+1];
				a[j+1] = t;
				change = TRUE;
			}
		}
	}
}

void print(int r[],int n)
{
   	int i;
   	for(i = 0; i < n; i++)
     	printf("%d ", r[i]);
   	printf("\n");
}

int main()
{
   int d[N]={49,38,65,97,76,13,27,49};
   printf("排序前:\n");
   print(d,N);
   bubble_sort(d,N);
   printf("排序后:\n");
   print(d,N);
}

3. 快速排序


快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

  一趟快速排序的算法是:
  1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
  2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
  3)从J开始向前搜索,即由后开始向前搜索(J=J-1即J--),找到第一个小于key的值A[j],A[j]与A[i]交换;
  4)从I开始向后搜索,即由前开始向后搜索(I=I+1即I++),找到第一个大于key的A[i],A[i]与A[j]交换;
  5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)


#include "ds.h"

#define 	MAX_SIZE 	20			// 一个用作示例的小顺序表的最大长度
typedef		int			KeyType;	// 定义关键字类型为整型
typedef 	int 		InfoType; // 定义其它数据项的类型

#define 	EQ(a,b) 	((a)==(b))
#define 	LT(a,b) 	((a)<(b))
#define 	LQ(a,b) 	((a)<=(b))

struct RedType						// 记录类型
{
	KeyType		key;				// 关键字项
	InfoType	otherinfo;			// 其它数据项,具体类型在主程中定义
};

struct SqList						// 顺序表类型
{
	RedType		r[MAX_SIZE+1];		// r[0]闲置或用作哨兵单元
	int 		length;				// 顺序表长度
};

// 交换顺序表L中子表L.r[low..high]的记录,使枢轴记录到位,
// 并返回其所在位置,此时在它之前(后)的记录均不大(小)于它。算法10.6(a)
int Partition(SqList &L,int low,int high)
{
#if 1
  	KeyType pivotkey;
   	L.r[0] = L.r[low]; // 用子表的第一个记录作枢轴记录
   	pivotkey = L.r[low].key; // 枢轴记录关键字
   	while(low < high)
   	{ // 从表的两端交替地向中间扫描
     	while(low<high&&L.r[high].key>=pivotkey)
       		--high;
     	L.r[low]=L.r[high]; // 将比枢轴记录小的记录移到低端
     	
     	while(low<high&&L.r[low].key<=pivotkey)
       		++low;
     	L.r[high]=L.r[low]; // 将比枢轴记录大的记录移到高端
   }
   L.r[low] = L.r[0]; // 枢轴记录到位
   return low; // 返回枢轴位置
#else
	RedType	t;
	KeyType	pivotkey;
	pivotkey = L.r[low].key;		// 用子表的第一个记录作枢轴记录
	
	while (low < high)
	{
		// 从表的两端交替地向中间扫描
		while (low < high && L.r[high].key >= pivotkey)
			--high;
		// 将比枢轴记录小的记录交换到低端
		t = L.r[low];
		L.r[low] = L.r[high];
		L.r[high] = t;
		
		while (low < high && L.r[low].key <= pivotkey)
			++low;
		
		// 将比枢轴记录大的记录交换到高端
		t = L.r[low];
		L.r[low] = L.r[high];
		L.r[high] = t;
	}
	return low;		// 返回枢轴所在位置
#endif
}

// 快速排序的函数,包括算法10.7、10.8
void QSort(SqList &L, int low, int high)
{
	// 对顺序表L中的子序列L.r[low..high]作快速排序。算法10.7
	int 	pivotloc;
	if (low < high)	// 长度大于1
	{
		pivotloc = Partition(L, low, high);	// 将L.r[low..high]一分为二
		QSort(L, low, pivotloc - 1);		// 对低子表递归排序,pivotloc是枢轴位置
		QSort(L, pivotloc + 1, high);		// 对高子表递归排序
	}
}

// 对顺序表L作快速排序。
void QuickSort(SqList &L)
{
	QSort(L, 1, L.length);
}


void print(SqList L)
{
   	int i;
   	for(i = 1; i <= L.length; i++)
     	printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
   	printf("\n");
}

#define N 8
int main()
{
   RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
   SqList l;
   int i;
   for(i=0;i<N;i++)
     l.r[i+1]=d[i];
   l.length=N;
   printf("排序前:\n");
   print(l);
   QuickSort(l);
   printf("排序后:\n");
   print(l);
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C语言基本数据结构之五(折半插入,堆排序,冒泡排序,快速排序,并归排序)

上一篇写了序列的查找算法,这次就聊聊序列的几种重要的排序

数据结构和算法分析之排序算法--交换排序篇(冒泡排序和快速排序)

1. 交换排序–冒泡排序基本思想: 在要排序的一组数中,对当前未排序好的范围全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的数往上冒,俗称冒泡。 总结:每当两相邻的数...

python数据结构学习笔记-2016-11-24-01-快速排序

12.2 快速排序         快速排序(quick sort)仍旧是采用分治法,该排序算法按照选定的主键(pivot key)将序列分成两部分。此外,该算法不需要使用临时数组。       ...

数据结构--排序算法(冒泡排序&&快速排序&&鸽巢排序)

插入排序以及选择排序请查阅我往期博客:http://blog.csdn.net/sayhello_world/article/details/61927082 冒泡排序: 思想:两两交换,大...

数据结构——选择排序、插入排序、冒泡排序、快速排序

数据结构——选择排序、插入排序、冒泡排序、快速排序

数据结构与算法——冒泡排序、选择排序和快速排序

冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是...

数据结构与算法从零开始系列:冒泡排序、选择排序、插入排序、希尔排序、堆排序、快速排序、归并排序、基数排序

本篇内容包含 排序的介绍 排序的C的实现 排序的Java的实现 排序的时间复杂度的计算 (一)冒泡排序1、基本思想:两个数比较大小,较大的数下沉,较小的数冒起来2、实现步骤:这张图就是将数字12,35...

Java数据结构和算法-简单排序(1-冒泡排序)

一般在创建数据库之后,就可能对某些数据进行排序。例如:对商店的销售品按价格排序,对城市按人口增长率进行排序等。排序一般作为检索的一个初始步骤,正如在前面所讲的数组中,二分查找要比线性查找快的多,但是二...

数据结构(排序)--冒泡排序

数据结构–选择排序 代码实现:package cn.hncu; //冒泡排序优化版----这种代码应该能够随手敲出来 public class bubbleSort { //优化版-----...

学习笔记1:冒泡排序, 快速排序

冒泡排序:每一次都从数组的最后一位开始两两比较,将值比较小的放前面,值大的放后面。每次都是把轻的气泡往上浮。第一轮比较结束之后,最轻的气泡就到了数组的第一位。接着比较数组的最后一位到数组的第二位,以此...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)