C语言排序算法

插入排序

直接插入排序

void InsertSort(SqList &L)
{//对顺序表L做直接插入排序
	for(i=2;i<=L.length;++i)     
		if(L.r[i].key<L.r[i-1].key)   //"<",需将r[i]插入有序子集
		{         
			L.r[0]=l.r[i];       //将待插入的记录暂存到监视哨中
			L.r[i]=L.r[i-1];       //r[i-1]后移
			for(j-i-2;L.r[0].key<L.r[j].key;--j)  //从后向前寻找插入位置
				L.r[j+1]=L.r[j];   //记录逐个后移,直到找到插入位置
			L.r[j+1]=L.r[0];   //将r[0]即原r[i],插入到正确位置
		}    //if
}

折半插入排序

void BInertSort(SqList &L)
{//对顺序表L做折半插入排序
	for(i=2;i<=L.length;++i)
	{ 
		L.r[0]=L.r[i]; //将待插入的记录暂存到监视哨中
		low=1;high=i-1;  //置查找区间初值
		while(low<=high)   //在r[low..high]中折半查找插入的位置
		{ 
			m=(low+high)/2; //折半
			if(L.r[0].key<L.r[m].key) high=m-1;  //插入点在前一子集
			else low=m+1;        //插入点在后一子集
		}  //while
		for(j=i-1;j>=high+1;--j) L.r[j+1]=L.r[j];   //记录后移
		L.r[high+1]=L.r[0];   //将r[0]即原r[i],插入到正确位置
	}     //for
}

希尔排序

void ShellInsert(SqList &L,int dk)
{//对顺序表L做一趟增量是dk的希尔插入排序
	for(i=dk+1;i<=L.length;++i)
		if(L.r[i].key<L.r[i-dk].key)  //需将L.r[i]插入有序增量子表
		{
			L.r[0]=L.r[i];  //暂存在L.r[0]
			for(j=i-dk;j>0&&L.r[0].key<L.r[j].key;j-=dk)
				L.r[j+dk]=L.r[j];  //记录后移,直到找到插入位置
			L.r[j+dk]=L.r[0];  //将r[0]即原r[i],插入到正确位置
		}   //if
}

void ShellSort(SqList &L,int dt[],int t)
{//按增量序列dt[0..t-1]对顺序表L作t趟希尔排序
	for(k=0;k<t;++k)
		ShellInsert(L,dt[k]);  //一趟增量为dt[t]的希尔插入排序
}

交换排序

冒泡排序

void BubbleSort(SqList &L)
{  //对顺序表L做冒泡排序
	m=L.length;flag=1;  //flag用来标记某一趟排序是否发生交换
	while((M>0)&&(flag==1))
	{ 
		flag=0;  //flag置为0;如果本趟排序没有发生交换,则不会执行下一趟排序
		for(j=1;j<=m;j++)
			if(L.r[j].key>L.r[j+1].key)
			{
				flag=1;  //flag置为1,表示本趟排序发生了交换
				t=L.r[j]; L.r[j]=L.r[j+1]; L.r[j+1]=t;  //交换前后两个记录
			}  //if
		--m; 
	}  //while
}   //BubbleSort

快速排序

int Partition(SqList &L,int low,int high)
{//对顺序表L中的子表r[low..high]进行一趟排序
	L.r[0]=L.r[low];   //用子表的第一个记录做枢轴记录
	pivotkey=L.r[low].key;  //枢轴记录关键字保存在pivotkey中
	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];  //将比枢轴记录大的记录移到高端
	} //while
	L.r[low]=L.r[0];   //枢轴记录到位
	return low;  //返回枢轴位置
}

void QSort(SqList &L,int low,int high)
{//调用前置初值:low=1;high=L.length;
//对顺序表L中的子序列L.r[low..high]做快速排序
	if(low<high)     //长度大于1  
	{ 
		pivotloc=Partition(L,low,high);  //将L.r[low..high]一分为二,pivotloc是枢轴位置
		QSort(L,low,pivotloc-1);  //对左子表递归排序
		QSort(L,pivotloc+1,high);  //对右子表递归排序
	}
}

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

选择排序

简单选择排序

void SelectSort(SqList &L)
{//对顺序表L做简单选择排序
	for(i=1;i<L.length;++i)   //在L.r[i..L.length]中选择关键字最小的记录
	{
		k=i;
		for(j=i+1;j<=L.length;++j)
			if(L.r[j].key<L.r[k].key) k=j; //k指向此趟排序中关键字最小的记录
		if(k!=i)
		{
			t=L.r[i]; L.r[i]=L.r[k]; L.r[k]=t; //交换r[i]与r[k]
		}   //for
	}
}

堆排序

1.调整堆

void HeapAdjust(SqList &L,int s,int m)
{//假设r[s+1..m]已经是堆,将r[s..m]调整为r[s]为根的大根堆
	rc=L.r[s];
	for(j=2*s;j<=m;j*=2)   //沿key较大的孩子结点向下筛选
	{
		if(j<m&&L.r[j].key<L.r[j+1].key) ++j;  //j为key较大的记录的下表
		if(rc.key>=L.r[j].key) break;  //rc应插入在位置s上
		L.r[s]=L.r[j];s=j;
	}            //for
	L.r[s]=rc;     //插入
}

2.建初堆

void GreatHeap(SqList &L)
{//把无序序列L.r[1..n]建成大根堆
	n=L.length;
	for(i=n/2;i>0;--i)      //反复调用HeapAdjust
		HeapAdjust(L,i,n);
}

3.堆排序

void HeapSort(SqList &L)
{//对顺序表L进行排序
	GreatHeap();  //把无序序列l.r[1...L.length]建成大根堆
	for(i=L.length;i>1;--i)
	{
		x=L.r[1];   //将堆顶记录和当前未经排序子序列L.r[1...i]中最后一个记录交换
		L.r[1]=L.r[i];
		L.r[i]=x;
		HeapAdjust[L,1,i-1];  //将L.r[1...i-1]重新调整成大根堆
	}          //for
}

归并排序

1.相邻两个有序子序列的归并

void Merge(RedType R[],RedType T[],int low,int mid,int high)
{//将有序表R[low..mid]和R[mid+1..high]归并为有序表T[low..high]
	i=low;j=mid+1;k=low;
	while(i<mid&&j<=high)  //将R中记录由小到大地并入T中
	{
		if(R[i].key<=R[j].key) T[k++]=R[i++];
		else T[k++]=R[j++];
	}  //while
	while(i<=mid) R[k++]=R[i++];  //将剩余的R[i..mid]复制到T中
	while(J<=high) T[k++]=R[j++];   //将剩余的R[j..mid]复制到T中
}

2.归并排序

void MSort(RedType R[],RedType T[],int low,int high)
{//R[low..high]归并排序后放入T[low..high]中
	if(low==high) T[low]=R[low];
	else
	{
		mid=(low+high)/2;  //将当前序列一分为二,求出分裂点mid
		MSort(R,S,low,mid); //对子序列R[low..mid]递归归并排序,结果放入S[low..mid]
		MSort(R,S,mid+1,high);  //对子序列R[mid+1..high]递归归并排序,结果放入S[mid+1..high]
		Merge(S,T,low,mid,high);//将S[low..mid]和S[mid+1..high]归并到T[low..high]
	}//else
}

void MergeSort(SqList &L)
{ //对顺序表L做归并排序
	MSort(L.r,L.r,1,L.length);
}

基数排序

void Distribute(SLCell &r,int i,ArrType &f,ArrType &e)
{//静态链表L的r域中记录已按(keys[0],...,keys[i-1])有序
//本算法按第i个关键字keys[i]建立RADIX个子集,使同一个表中记录的keys[i]相同
//if[0..RADIX-1]和e[0...RADIX-1]分别指向各子集中第一个和最后一个记录
	for(j=0;j<RADIX;++j) f[j]=0;    //各子集初始化为空表
	for(p=r[0].next;p;p=r[p].next)
	{
		j=ord(r[p].keys[i]);  //ord将记录中第i个关键字映射到[0...RADIX-1]
		if(!f[j]) f[j]=p;
		else r[e[j]].next=p;
		e[j]=p;      //将p所指的结点插入第j个子集中
	}   //for
} 

void Collect(SLCell &r,int i,ArrType f,ArrType e)
{//本算法按keys[i]自小至大地将f[0...RADIX-1]所指各子集依次连接成一个链表
//e[0...RADIX-1]为各子集的尾指针
	for(j=0;!f[j];j=succ(j));  //找第一个非空子集,succ为求后继函数
	r[0].next=f[j]; t=e[j];  //r[0].next指向第一个非空子集中第一个结点
	while(j<RADIX)
	{
		for(j=succ(j);j<RADIX-1&&!f[j];j=succ(j));  //找下一个非空子集
		if(f[j]) {r[t].next=f[j]; t=e[j];  //链接两个非空子集
	}  //while
	r[t].next=0;  //t所指向最后一个非空子集中的最后一个结点
}

void RadixSort(SLList &L)
{//L是采用静态链表表示的链表
//对L做基数排序,使得L成为按关键字自小到大的有序静态链表,L.r[0]为头结点
	for(i=0;i<L.recnum;++i) L.r[i].next=i+1;
	L.r[L.recnum].next=0;  //将L改造成静态链表
	for(i=0;i<L.keynum;i++) //按最低位优先依次对各关键字进行分配和收集
	{
		Distribute(L.r,i,f,e);  //第i趟分配
		Collect(L.r,i,f,e);  //第i趟收集
	}  //for
}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值