排序总结,插入排序(折半插入,二路插入),希尔排序,冒泡排序,快排,选择排序,堆排序,归并排序,基数排序

插入排序(基本插入,折半插入,二路插入)

(基本插入):需要一个哨兵位存放需要插入的值(这里把a[0]作为哨兵位)从第二个数开始插入,把第二个数放在a[0]里面,与前面的数一次进行比较

void InsertSort(int ar[],int n)
{
	for(int i = 2;i<=n;++i)
	{
		ar[0] = ar[i];
		for(int j = i-1;ar[0]<ar[j];--j)
			ar[j+1] = ar[j];
		ar[j+1] = ar[0];
	}
}

(折半插入未做):

(二路插入):创建一个临时数组,用start和finish作为起始末尾下标

void TWayInsert(int ar[],int n)
{
	int *tmp = (int*)malloc(sizeof(int)*n);
	assert(tmp != NULL);
	int start,finish;
	start = finish = 0;
	tmp[0] = ar[0];
	for(int i=1;i<n;++i)
	{
		if(ar[i]<tmp[start])
		{
			start = (start-1+n)%n;
			tmp[start] = ar[i];
		}
		else if(ar[i] > tmp[finish])
			tmp[++finish] = ar[i];
		else  //start<  <finish
		{
			tmp[++finish] = tmp[finish-1];
			for(int j= finish-1;ar[i]<tmp[(j-1+n)%n];j = (j-1+n)%n)
				tmp[j] = tmp[(j-1+n)%n];
			tmp[j] = ar[i];
		}
	}
	for(i=0;i<n;++i)
	{
		ar[i] = tmp[start];
		start = (start+1)%n;
	}
	free(tmp);
}

希尔排序:引入增量dlta,把原始数据分割成很多小数组的插入排序

void ShellInsert(int ar[],int n,int dk)
{
	int tmp;
	for(int i=dk;i<n;++i)
	{
		if(ar[i]<ar[i-dk])
		{
			tmp = ar[i];
			ar[i] = ar[i-dk];
			for(int j=i-dk;j-dk>0;j-=dk)
			{
				if(tmp<ar[j-dk])
					ar[j] = ar[j-dk];
				else
					break;
			}
			ar[j] = tmp;
		}
	}
}

void ShellSort(int ar[],int n)
{
	int dlta[] = {5,3,2,1};
	int k = sizeof(dlta)/sizeof(int);
	for(int i=0;i<k;++i)
	{
		ShellInsert(ar,n,dlta[i]);
	}
}

冒泡排序:比较相邻两个值的大小,如果前面的>后面的就交换位置。两个for循环,第一个for是趟数,1-5趟;第二个for是每趟循环

void InsertSort(int ar[],int n)
{
	for(int i = 1;i<n;++i)
	{
		for(int j=0;j<n-i;++j)
		{
			if(ar[j]>ar[j+1])
			{
				int tmp = ar[j];
				ar[j] = ar[j+1];
				ar[j+1] = tmp;
			}
		}
	}
}

快排:找一个数,左边 < 这个数 < 右边,再对左右进行递归
 

int Partition(int ar[],int low,int high)
{
    int key = ar[low];
    while(low<high)
    {
        while(low<high && ar[high]>=key)
            high--;
        Swap(ar[low],ar[high]);
        while(low<high && ar[low]<=key)
            low++;
        Swap(ar[low],ar[high]);
    }
    return low;
}
void QuikSort(int ar[],int low,int high)
{
    if(low<high)
    {
        int key_pos = Partition(ar,low,high);
        QuikSort(ar,low,key_pos-1);
        QuikSort(ar,key_pos+1,high);
    }
}

选择排序:找最小值第一趟和a[0]换,第二趟和a[1]换
 

int FindMin(int ar[],int start,int finish)
{
    int min_pos = start;
    for(int i=start+1;i<=finish;++i)
    {
        if(ar[min_pos]>ar[i])
            min_pos = i;
    }
    return min_pos;
}
void SelectSort(int ar[],int n)
{
    for(int i=0;i<n;++i)
    {
        int min_pos = FindMin(ar,i,n-1);
        Swap(ar[i],ar[min_pos]);
    }
}

堆排序(未做)

归并排序(未做)

基数排序:不停的分发,回收数据,直到有序,Distribute,Collect(利用list库)

list<int>  ls[10];
void Contribute(int ar[],int n,int k)
{
    int tmp;
    int x;
    for(int i=0;i<n;++i)
    {
        tmp = ar[i];
        x = k;
        while(tmp && x > 0)
        {
            tmp /= 10;
            x--;
        }
        ls[tmp%10].push_back(ar[i]);
    }
}

void Collect(int ar[],int n)
{
    int k = 0;
    for(int i=0;i<n;++i)
    {
        while(!ls[i].empty())
        {
            ar[k++] = ls[i].front();
            ls[i].pop_front();
        }
    }
}
void RadixSort(int ar[],int n)
{
    for(int i=0;i<3;++i)
    {
        Contribute(ar,n,i);
        Collect(ar,n);
    }
}

Swap()方法

template<class Type>
void Swap(Type &a,Type &b)
{
	Type tmp;
	tmp = a;
	a = b;
	b = tmp;
}

测试代码:main()

#include<iostream>
#include<assert.h>
#include<list>
using namespace std;
void main()
{
	int ar[] = {278, 109, 63, 930, 589, 184, 505, 269, 8, 83};
	int n = sizeof(ar)/sizeof(int);

	RadixSort(ar,n);//自己换Sort
	
	for(int i=0;i<n;++i)
		cout<<ar[i]<<" ";
	cout<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_42244208/article/details/81613048