插入排序、選擇排序、冒泡排序、快速排序、堆排序

設待排序數組爲a[n]

(1)直接插入排序

思想:將數組a[n]分爲一個有序區a[1]...a[i] 和一個無序區a[i+1]....a[n-1],每一次將a[i+1]插入有序區,形成一個新的有序區,如此反覆。

代碼如下:

 

#include "stdafx.h"
#include <iostream>

using namespace std;

typedef int type;
//直接插入排序
void InsertSort(type a[],int n)
{
	int i,j;
	type temp;
	
	for(i=1;i<n;i++)
	{
	   temp=a[i];
	   for(j=i;j>0 && a[j-1]>temp;j--)
	   {
	     a[j]=a[j-1];
	   }
	   a[j]=temp;
	}
}
(2)直接選擇排序

思想: 將數組a[n]分爲一個有序區a[1]...a[i] 和一個無序區a[i+1]....a[n-1],每次將無序區最大或最小的值找出,並置於有序區尾部。

代碼如下:

//直接選擇排序
void ChooseSort(type  a[],int n)
{
	int i,j;
	type temp;

	for(i=0;i<n;i++)
	{
	  temp=a[i];
	  for(j=i+1;j<n;j++)
	  {
	    if(a[j]<temp)
		{
		  a[i]=a[j];
		  a[j]=temp;
		}
	  }
	}
}

(3)冒泡排序

思想:數組a[0]...a[n-1]垂直排列,從數組尾部開始向數組首部開始掃描,a[i]與a[i-1]相比較, 滿足條件(大或小),兩兩交換。

代碼如下:

//冒泡排序
void BubbleSort(type a[],int n)
{
	int i,j;
	type temp;
	for(i=1;i<n;i++)
	{

	  for(j=n-1;j>=i;j--)
	  {
	     if(a[j-1]<a[j])
		 {
		   temp=a[j];
		   a[j]=a[j-1];
		   a[j-1]=temp;
		 }
	  }
	 
	}

(4)快速排序

思想: 在a[0]...a[n-1]中選取一個記錄(例如a[i])將無序區分爲左右兩個子區間,使得左區間a[0]...a[i-1]的值都小於等於a[i],右區間a[i+1]...a[n-1]的值都大於等於a[i]的值,而a[i]則位於正確的位置,不需要參加後續排序。通過遞歸調用分別對左右兩個子區間進行快速排序。

代碼如下:

//快速排序
void QuickSort(type a[],int left, int right)
{
	int i,j;
	if(left>right)
		return;
	i=left;
	j=right;

	type temp=a[i];
	while(i!=j)
	{
	   while((a[j]>temp)&&(j>i))
		   j--;
       if(j>i)
	   {
	     a[i++]=a[j];
	   }
	   
	   while((a[i]<temp)&&(i<j))
		   i++;
	   if(i<j)
	   {
	     a[j--]=a[i];
	   }
	}
	a[i]=temp;
	QuickSort(a,left,i-1);
	QuickSort(a,i+1,right);
}

(5)堆排序

思想: 首先建造一個初始大堆;其次,每一趟排序都是將當前無序區的堆頂記錄a[0]和區間最後一個記錄交換,將新的無序區調整爲堆。

//堆排序
//生成大根堆
//調整以spoint爲根結點的二叉樹爲大堆  n爲數組大小

void Swap(type *a,type *b)
{
	type temp;
	temp=*a;
	*a=*b;
	*b=temp;
}

void CreateHeep(type a[],int spoint, int n)
{
	
	while((2*spoint+1)<n) //左子樹根結點值還在數組中
	{
	  int mpoint=2*spoint+1;
	  if((mpoint+1)<n) //右子樹根結點值處於數組中
	  {
	    if(a[mpoint]<a[mpoint+1]) //判斷左右子樹的最大值
		{
		
		  mpoint=mpoint+1;
		}
	  }
	  
	  if(a[spoint]<a[mpoint])//如果根結點值小於左右子樹中的最大值  則交換
	  {
	    Swap(&a[spoint],&a[mpoint]); //交換值
		spoint=mpoint; //交換後,繼續查看以新的spoint爲根結點的子樹是否滿足大堆要求
	  }
	  else
	  {
	   break;
	  }
	
	}

}

void HeepSort(type a[],int n)
{

	int i;
	for(i=(n/2-1);i>=0;i--) //根據數組創建大堆
	{
	  CreateHeep(a,i,n);
	}
	
	for(i=(n-1);i>=1;i--) //堆排序
	{
	  Swap(&a[i],&a[0]);//堆頂元素和最後一個元素交換
	  CreateHeep(a,0,i);
	}
}

(6)歸併排序

思想: 分治法,先講一個待排序數組遞歸分區,直至分爲2個有序數組爲止(數組中只有一個元素時,則肯定有序);  而後將2個排好序的數組進行合併.

代碼如下:

//歸併排序
void MergeSort(type *a,int left,int mid,int right)
{

	int i=left;
	int j=mid+1;
	int k=0;

	type *temp=new type[right-left+1];
	while((i<=mid)&&(j<=right))
	{
	   if(a[i]<a[j])
	   {
	      temp[k++]=a[i++];
	   }
	   else
	   {
	    temp[k++]=a[j++];
	   }
	}
	while(i<=mid)
	{
	  temp[k++]=a[i++];
	}
	while(j<=right)
	{
	  temp[k++]=a[j++];
	}

	for(int r=0;r<(right-left+1);r++)
	{
	  a[r+left]=temp[r];
	}
	delete []temp;
}
void MergeSortFunction(type *a, int left, int right)
{
   if(left<right)
   {
      int mid=(left+right)/2;
	  MergeSortFunction(a,left,mid);
	  MergeSortFunction(a,mid+1,right);
	  MergeSort(a,left,mid,right);
   }
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章