数据结构之常用c语言排序算法
Posted yunshouhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之常用c语言排序算法相关的知识,希望对你有一定的参考价值。
#include <iostream>
#include <string.h>
using namespace std;
#define NUM 16
#define MAX 100
#define MAX_LINE_NUMBER 16
int list[NUM*7]={0};
int merge_list[NUM*10]={0};
int merge_link[NUM*10]={0};
void init();
void init_list(int);
void out(int[],int ,int);
void swap(int,int);
//1. 直接插入排序
void insert_sort(int len)
{
int insertNum;
for (int i = 0; i < len; ++i) {
insertNum=list[i];//待插入元素
int j=i;
//寻找插入位置
while(j>0 && insertNum < list[j-1])
{
list[j]=list[j-1];
j--;
}
list[j]=insertNum;
}
}
//2. 二分插入排序
void binary_insert_sort(int len)
{
int middle=-1;
for (int i = 0; i < len; ++i) {
int insertNumber=list[i];//待插入元素
int left=0;
int right=i-1;
while(left <= right)//二分法寻找插入位置
{
middle=(left+right)/2;
if(insertNumber > list[middle])
left=middle+1;
else
right=middle-1;
}
for (int j = i; j >left; j--) {
list[j]=list[j-1];
}
list[left]=insertNumber;
}
}
//3. 希尔排序
void shell_sort(int len)
{
int insertNum=-1;
int gap=len/2;//初始化增量
while(gap)//当gap>=1
{
for (int i = gap; i < len; ++i) {//对gap间隔子序列进行插入排序
insertNum=list[i];//待插入元素
int j=i;
while(j>=gap && insertNum < list[j-gap])//寻找插入位置
{
list[j]=list[j-gap];
j -=gap;
}
list[j]=insertNum;//插入
}
gap=gap/2;//缩小增量
}
}
//4. 直接选择排序
void select_sort(int len)
{
int k=-1;
for (int i = 0; i < len; i++) {
k=i;
for (int j = i+1; j < len; j++) {//找最小元素
if(list[j] < list[k])
{
k=j;
}
}
swap(i,k);//将最小元素放入i位置
}
}
//5. 堆排序
//堆的建立或调整
void heap_build(int current,int last)
{
int child=2*current+1;//child为current的子女位置
int temp=list[current];//暂存子root节点
while(child<=last)//判断是否到最后结尾
{
if(child<last && list[child] <list[child+1])
{
child++;//让child指向两子女中的最大值
}
if(temp >= list[child])
break;//temp的关键码大则不做调整
else{
//否则子女中的大则上移
list[current]=list[child];
current=child;
child=2*child+1;
}
}
list[current]=temp;//temp中暂存的元素放到合适位置
}
void heap_sort(int len)
{
//建立堆
for (int i = (len-2)/2; i >=0 ; i--) {
heap_build(i,len-1);
}
//不断调整为最大堆
for (int i = len-1; i >0; i--) {
swap(0,i);
heap_build(0,i-1);
}
}
//6. 冒泡排序
/**
* 优化冒泡排序 附上解释
* 一次优化。我们可以想到这种极端情况:array本身就是排序好的,但是依照如上算法,我们仍然要遍历n平方/2次。原因在于,我们没有机制检查数组是否是排序好的。
* 解决办法就是加入标识项,如果发现一次内层循环没有经过任何交换,则说明array已经排序完毕,需要直接跳出循环。
*/
void bubble_sort(int len)
{
for (int i=0;i<len;i++)
{
bool sorted = true;//考虑有序,减少趟数
for (int j = i+1; j < len; ++j) {
if(list[i] > list[j])
{
int temp=list[i];
list[i]=list[j];
list[j]=temp;
sorted= false;//考虑有序,减少趟数
}
}
//如果上一轮冒泡排序已经全部有序 即flag!=false,则直接退出,不用进行下一轮冒泡循环,提高效率,否则数组已经有序了,他还会继续冒泡循环
if (sorted) {
break;
}
}
}
void bubble_sort_simple(int len)
{
for (int i=0;i<len;i++)
{
for (int j = i+1; j < len; ++j) {
if(list[i] > list[j])
{
swap(i,j);
}
}
}
}
//7. Shaker排序
void shaker_sort(int len)
{
int i=0,shift=0;
int left=0;
int right=len-1;
while(left <right)
{
for (i = left; i<right;i++) {//向右进行气泡排序
if(list[i] >list[i+1])
{
swap(i,i+1);
shift=i;
}
}
right=shift;
for (i = right; i >left; i--) {//向左进行气泡排序
if(list[i] <list[i-1])
{
swap(i,i-1);
shift=i;
}
}
left=shift;
}
}
//8. 快速排序
void quick_sort(int left,int right)
{
int i=left;
int j=right;
int pivot=list[left];//基数
while(i<j)
{
while(i<j && list[j] >= pivot) j--;//找到比基数小的元素
if(i<j) swap(i,j);
while (i<j && list[i] <=pivot) i++;//找到比基数大的元素
if(i<j) swap(i,j);
}
if(i!=left)
{
quick_sort(left,i-1);
}
if(j!=right)
{
quick_sort(j+1,right);
}
}
//9. 归并排序
//具体方法:以merger_link[]提供链表功能。merger_link[i]对应在有序子序列中
//merger_list[i]后一个结点在原merger_list[]中的下标;
//merger_link[0]总是表示有序子序列开始的结点在merge_list[]中的下标;
//st1,st2为两个有序序列的第一个结点;
//将他们归并,并返回其第一个结点的下标,即merger_link[0]
int list_merge(int st1,int st2)
{
int k=0;
int i=st1,j=st2;
while(i && j)//当两序列未检测完
{
if(merge_list[i] <= merge_list[j])
{
//将merge_list[i]和merge_list[j]中小的连接到merger_link[k]
merge_link[k]=i;
k=i;
i=merge_link[i];
}else{
merge_link[k]=j;
k=j;
j=merge_link[j];
}
}
//将剩余未检测完的merge_list[]连接到merger_link[k]后
if(!i)
merge_link[k]=j;
else
merge_link[k]=i;
return merge_link[0];
}
int merge_sort(int left,int right)
{
if(left>=right)
return left;
int middle=(left+right)/2;
//对左右两个子序列进行归并
int st1=merge_sort(left,middle);
int st2=merge_sort(middle+1,right);
return list_merge(st1,st2);
}
//10. 计数排序
void counting_sort(int len,int max)
{
int result[NUM]={0}; //临时保存结果
int* mark=new int[max]; //标记无序表中元素
memset(mark,0,max*sizeof(int));
for (int i = 0; i < len; ++i) {
mark[list[i]]++; //统计元素出现次数
}
for (int i = 1; i < max; ++i) {
mark[i] +=mark[i-1];//计算元素在有序表中位置
}
for (int i = len-1; i >=0 ; i--) {
result[mark[list[i]]-1] =list[i];//通过mark[]直接将list[i]有序存入result[]
mark[list[i]]--;
}
delete[] mark;
//转存到list以便输出结果
for (int i = 0; i < len; ++i) list[i]=result[i];
}
//数据结构之常用c语言排序算法
int main() {
init();
int input;
while(true)
{
cout<<"请选择:";
cin>>input;
init_list(input);
switch (input) {
case 1: insert_sort(NUM); break;
case 2: binary_insert_sort(NUM); break;
case 3:shell_sort(NUM);break;
case 4:select_sort(NUM);break;
case 5:heap_sort(NUM);break;
case 6:bubble_sort(NUM);break;
case 7:shaker_sort(NUM);break;
case 8:quick_sort(0,NUM-1);break;
case 9:merge_sort(1,NUM);break;
case 10:counting_sort(NUM,MAX);break;
case 0:exit(0);break;
}
cout<<"排序结果:"<<endl;
if(input !=9) {
out(list,0,NUM);
}else{
int i=merge_link[0];
int j=0;
while(i)
{
j++;
cout<<merge_list[i]<<" ";
i=merge_link[i];
if(j % MAX_LINE_NUMBER ==0 )
cout<<endl;
}
cout<<endl;
}
}
return 0;
}
// 初始化界面
void init() {
cout << endl;
cout << " 十种常用排序算法(升序)" << endl;
cout << " ---------------------------------" << endl;
cout << " 1. 直接插入排序" << endl;
cout << " 2. 二分插入排序" << endl;
cout << " 3. 希尔排序" << endl;
cout << " 4. 直接选择排序" << endl;
cout << " 5. 堆排序" << endl;
cout << " 6. 冒泡排序" << endl;
cout << " 7. Shaker排序" << endl;
cout << " 8. 快速排序" << endl;
cout << " 9. 归并排序" << endl;
cout << " 10.计数排序" << endl;
cout << " 0. 退出" << endl;
cout << " ---------------------------------" << endl;
}
//初始化无序表
void init_list(int input)
{
if(input ==0) return ;
cout<<"待排数列为:"<<endl;
if(input == 9)
{
for(int i=1;i<=NUM;i++)
{
merge_list[i]=rand() % MAX;
merge_link[i]=0;
}
out(merge_list,1,NUM);
}else{
for (int i = 0; i < NUM; ++i) {
list[i]=rand()% MAX;
}
out(list,0,NUM);
}
}
//打印输出结果
void out(int result[],int st,int len)
{
for (int i = st; i < st+len; ++i) {
cout<<result[i]<<" ";
if((i+1) % (MAX_LINE_NUMBER+st) == 0)
cout<<endl;
}
}
void swap(int i,int j)
{
int temp=list[i];
list[i]=list[j];
list[j]=temp;
}
以上是关于数据结构之常用c语言排序算法的主要内容,如果未能解决你的问题,请参考以下文章