数据结构排序之“九阳神功”

在这里推荐一下大神的关于排序算法的博客

https://www.cnblogs.com/onepixel/p/7674659.html
一、交换排序
  1. 冒泡排序
  2. 快速排序
二、插入排序
  1. 直接插入排序
  2. 折半插入排序
  3. 希尔排序
三、选择排序
  1. 简单选择排序
  2. 堆排序
四、归并排序
五、桶排序

一、交换排序
1.冒泡排序

基本思想:
每次比较两个相邻的元素,如果它们顺序错误就把它们交换过来。

/*BubbleSort  冒泡排序*/ 
void swap(int *a,int *b)
{
      int *t;
      t=a;a=b;b=t;
}
void BubbleSort(int R[],int n)   //R[]为要排序数组,n为数组长度 
{
	for(int i=0;i<n-1;i++)
	{
		for(int j=n-1;j>i;j--)           //从右向左排序
		{
			if(R[j]<R[j-1])
			swap(R[j],R[j-1]);//交换函数 
		}
	}
}

/*改进冒泡排序*/
void BubbleSort(int R[],int n)
{
	bool exchange;
	for(int i=0;i<n-1;i++)
	{
		exchange=false;
		for(int j=n-1;j>i;j--)
		if(R[j]<R[j-1])
		{
			swap(R[j],R[j-1]);
			exchange=true;
		}
		if(!exchange)//此处为该改进算法的关键之处,节省了没有交换; 
		return;
	}
 } 

该程序冒泡排序为从左向右排序

#include<stdio.h>
int main()
{
	int a[100],i,j,t,n;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	
	for(i=0;i<n-1;i++)     //(n-1)次排序 
	{
		for(j=0;j<n-i-1;j++)   //从左向右排序     n-i-1是其比较次数 
		if(a[j]<a[j+1])          //成升序排序 
		{
			t=a[j];a[j]=a[j+1];a[j+1]=t;
		}
	}
	for(i=0;i<n;i++)
	printf("%d ",a[i]);
	
	return 0;
}
2.快速排序
/*Quick Sort*/
int partition(int R[],int i,int j)//i为0,j为R.length 
{
	int tmp=R[i];
	while(i<j){
		while(i<j&&R[j]>=tmp)//从右向左扫描 
		j--;
		R[i]=R[j];
		while(i<j&&R[i]<=tmp)//从左向右扫描 
		i++;
		R[j]=R[i];
	}
	R[i]=tmp;//哨兵回到它自己的位置 
	return i;
} 
void QuickSort(int R[],int i,int j)
{
	int a;
	if(i<j){
		i=partition(R,i,j);
		QuickSort(R,i,a-1);       //对左区间递归排序 
		QuickSort(R,a+1,j);       //对右区间递归排序 
	}
 } 
二、插入排序
1.直接插入排序
/*InsertSort*/
 void InsertSort(int R[],int n)
 {
 	int i,j,tmp;
 	for(i=1;i<n;i++)
	{
 		if(R[i]<R[i-1])
		{
			tmp=R[i];
 			j=i-1;
 			do
 			{
 				R[j+1]=R[j];
 				j--;
			}while(j>=0&&R[j]>tmp);       //在有序区内寻找比tmp小的值,将tmp插入此值的后面 
			R[j+1]=tmp;
		}
	}
  } 
2.折半插入排序
/*BinInsertSort=BinarySearch+InsertSort*/
void BinInsertSort(int R[],int n)
{
	int i,j,low,high,mid,tmp;
	for(i=1;i<n;i++)
	{
		if(R[i]<R[i-1])
		{
			tmp=R[i];
			low=0;high=i-1;
			while(low<=high)
			{
				mid=(low+high)/2;
				if(tmp<R[mid])
				high=mid-1;
				else
				low=mid+1;
			}
			for(j=i-1;j>=mid;j--) //将元素往后移动,为插入元素做准备
			 R[j+1]=R[j];
			R[mid]=tmp;
		}
	}
 } 
3.希尔排序
 /*ShellSort*/
 void ShellSort(int R[],int n)
 {
 	int i,j,d,tmp;
 	d=n/2;
 	while(d>0)
 	{
 		for(i=d;i<n;i++)
 		{
 			tmp=R[i];
 			j=i-d;
 			while(j>=0&&tmp<R[j])
 			{
 				R[j+d]=R[j];
 				j=j-d;
			 }
			 R[j+d]=tmp;
		 }
		 d=d/2;
	 }
 }
三、选择排序
1.简单选择排序
/*simple selection sort  与冒泡排序类似*/
void swap(int *a,int *b)
{
	int tmp;
	tmp=a;a=b;b=tmp;
}
void SelectSort(int R[],int n)
{
	int k;
	for(int i=0;i<n-1;i++)
	{
		k=i;
		for(j=i+1;j<n;j++)
		if(R[j]<R[k])
		k=j;
		if(k!=i)
		swap(R[i],R[k]);
	}
}
2.堆排序
var len;    // 因为声明的多个函数都需要数据长度,所以把len设置成为全局变量
 
function buildMaxHeap(arr) {   // 建立大顶堆
    len = arr.length;
    for (var i = Math.floor(len/2); i >= 0; i--) {
        heapify(arr, i);
    }
}
 
function heapify(arr, i) {     // 堆调整
    var left = 2 * i + 1,
        right = 2 * i + 2,
        largest = i;
 
    if (left < len && arr[left] > arr[largest]) {
        largest = left;
    }
 
    if (right < len && arr[right] > arr[largest]) {
        largest = right;
    }
 
    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, largest);
    }
}
 
function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
 
function heapSort(arr) {
    buildMaxHeap(arr);
 
    for (var i = arr.length - 1; i > 0; i--) {
        swap(arr, 0, i);
        len--;
        heapify(arr, 0);
    }
    return arr;
}
四、归并排序
/*MergeSort*/
void Merge(int array[], int left, int m, int right)
{
    int aux[Max_] = {0};  // 临时数组 (若不使用临时数组,将两个有序数组合并为一个有序数组比较麻烦)
    int i; //第一个数组索引
    int j; //第二个数组索引
    int k; //临时数组索引
    
    for (i = left, j = m+1, k = 0; k <= right-left; k++) // 分别将 i, j, k 指向各自数组的首部。
    {
        //若 i 到达第一个数组的尾部,将第二个数组余下元素复制到 临时数组中
        if (i == m+1)
        {
            aux[k] = array[j++];
            continue;
        }
        //若 j 到达第二个数组的尾部,将第一个数组余下元素复制到 临时数组中
        if (j == right+1)
        {
            aux[k] = array[i++];
            continue;
        }
        //如果第一个数组的当前元素 比 第二个数组的当前元素小,将 第一个数组的当前元素复制到 临时数组中
        if (array[i] < array[j])
        {
            aux[k] = array[i++];
        }
        //如果第二个数组的当前元素 比 第一个数组的当前元素小,将 第二个数组的当前元素复制到 临时数组中
        else
        {
            aux[k] = array[j++];
        }
    }
    
    //将有序的临时数组 元素 刷回 被排序的数组 array 中,
    //i = left , 被排序的数组array 的起始位置
    //j = 0, 临时数组的起始位置
    for (i = left, j = 0; i <= right; i++, j++)
    {
        array[i] = aux[j];
    }
}
 
// 归并排序
void MergeSort(int array[], int start, int end)
{
    if (start < end)
    {
        int i;
        i = (end + start) / 2;
        // 对前半部分进行排序
        MergeSort(array, start, i);
        // 对后半部分进行排序
        MergeSort(array, i + 1, end);
        // 合并前后两部分
        Merge(array, start, i, end);
    }
}
五、桶排序
#include<stdio.h>
int main()
{
	int a[11],i,j,t;
	for(i=0;i<=10;i++)
	a[i]=0;
	
	for(i=1;i<=5;i++)
	{
		scanf("%d",&t);
		a[t]++;
	}
	
	for(i=10;i>=0;i--)
	for(j=1;j<=a[i];j++)
	printf("%d ",i);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值