C语言排序算法

         通常,在排序过程中需要进行下列两种操作:(1)比较两个关键字的大小;(2)将记录从一个位置移到另一个位置。前一个操作对大多数排序方法来说都是必须的,而后一个操作可以通过改变记录的存储方式来予以避免。
         待排序的记录序列可有一下三种存储方式:(1)待排序的一组记录存储在地址连续的一组存储单元上。它类似于线性表的数序存储结构,在序列中相邻的两个记录Rj和Rj+1,它们的存储位置也相邻。在这种存储方式中,记录之间的次序关系由其存储位置决定,则实现排序必须借助移动记录;(2)一组待排序记录存放在静态链表中,记录之间的次序关系有指针表示,则实现不需要移动记录,仅需修改指针即可;(3)待排序记录本身存储在一组地址连续的存储单元,同时另设一个指示各个记录存储位置的地址向量,在排序过程中不易懂记录本身,而移动地址向量中这些记录的“地址”,在排序结束后再按照地址向量中的值调整记录的存储位置。在第二种存储方式下实现的排序又称(链)表排序,在第三种排序方式下实现的排序又称为地址排序。


       直接插入排序(Straight Insert Sort)是一种最简单的排序方法,它的基本操作是将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。

void SInsertSort(ArrayType R[], int n)
{
	int i, j, temp;
	for(i=1;i<n;i++) //i从第二个元素开始
	{
		temp = R[i];   //将待排序元素放入临时变量
		j = i-1;      //从第i个元素的前一个元素开始查找
		while((temp<R[j]) && (j>=0))
		{
			R[j+1] = R[j];   //元素向后移动
			j--;     //向左继续查找
		}
		R[j+1] = temp;  //将元素插入相应位置
	}
}

      折半插入排序(Binary Insertion Sort)是利用二元搜索的方法对每一个R[i]找其插入位置。具体实现是用两个指针:一个头指针h,初始指向第一个记录;一个尾指针t,初始指向带插入记录的前面一个位置。每次将待插记录的关键字与它前面一段的中间位置的关键字比较,确定待插记录的位置。

void BInsertSort(ArrayType R[], int n)
{
	int i, j, temp, middle;
	int head, tail;
	for(i=1;i<n;i++)
	{
		temp = R[i];
		head = 1;   //在R[head]到R[tail]中折半查找插入位置
		tail = i - 1;
		while(head <= tail)
		{
			middle = (head + tail)/2;   //折半
			if(temp < R[middle])
				tail = m-1;      //插入点在低半区
			else
				head = m+1;      //插入点在高半区
		}
		for(j = i-1;j >= tail+1;--j)  //将tail之后的元素后移
			R[j+1] = R[j];
		R[tail + 1] = temp;    //插入
	}
}

选择排序:

void selectSort(int *x, int n)
{
	int i, j, min, t;
	for(i=0; i<n-1; i++)//要选择的次数
	{
		min = i;
		for(j=i+1; j<n; j++)//找出最小的数的下标
		{
			if(*(x+j) < *(x+min))
				{
					min = j;
				}
		}
		if(min != i)
			{
				t = *(x+i);
				*(x+i) = *(x+min);
				*(x+min) = t;
			}
	}
}

冒泡排序:
void bubbleSort(int *x, int n)
{
	int j, k, h, t;
	int flag=1;
	for(h=n-1; h>0; h=k) //一直循环到没有比较范围
	{
		for(j=0,k=0; j<h; j++) //每次预设k=0,循环扫描完成后更新k
		{
			if(*(x+j)>*(x+j+1))  //大的沉下去,小的浮上来
				{
					t = *(x+j);
					*(x+j) = *(x+j+1);
					*(x+j+1) = t;
					k = j; //保存最后下沉位置,这样k后面的都是排序完成的
					flag = 0; 
				}
		}
		if(flag)
			{
				break; //如果一次都未交换,说明已经排好序
			}
	}
}

希尔排序:
void shellSort(int *x, int n)
{
	int h, j, k, t;
	for(h=n/2; h>0; h/=2) //控制增量
	{
		for(j=h; j<n; j++)  //这个实际就是直接插入排序
		{
			t = *(x+j);
			for(k=j-h; k>=0&&t<*(x+k); k-=h)
			{
				*(x+k+h) = *(x+k);
			}
			*(x+k+h) = t;
		}
	}
}

快速排序:
void quickSort(int *x, int low, int high)
{
	int i, j, t;
	if(low < high) //要排序元素的下标,以下标为low的元素为基准点
		{
			i = low;
			j = high;
			t = *(x+low); //暂存基准点的数
			while(i<j)
			{
				while(i<j && *(x+j)>t)
				//在右边的,只要比基准点大的元素仍放在右边
				{
					j--; //前移一个位置
				}
				if(i<j)
					{
						*(x+i) = *(x+j);
						//上面的循环退出,即出现比基准点小的数,替换左边的数
						i++; //后移一个位置
					}
				while(i<j && *(x+i)<=t)
				//在基准点左边的数,只要比基准点小的元素仍放在左边
				{
					i++;
				}
				if(i<j)
					{
						*(x+j) = *(x+i);
						j--;
					}
			}
			*(x+i) = t;//放入适当位置
			quickSort(x, low, i-1);//对基准点左边的数进行快排
			quickSort(x, i+1, high);//对基准点右边的数进行快排
		}
}

以上仅仅写出了大体算法,由于没有实际编译,所以不排除有细节问题,如有发现,请指正,谢谢。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值