【数据结构】排序

数据表(dataList):待排元素的集合。

排序码(key):排序的关键字。

排序的稳定性:若相等的两个元素经过排序后顺序仍不变则称排序算法是稳定的。

一个b站学习视频

一、快速排序

(一)原理
选择一个元素作为基准元素,将小于基准元素的都放在其左边,将大于基准元素的都放在其右边。这样序列就被划分为大于和小于基准元素的两部分。对这两部分分别递归处理。基准元素随意选。
(二)代码

//快速排序---我自己的板子
#include
#include
#define N 100009
using namespace std;

int n;
int a[N];

void qsort(int l,int r)
{
	int mid=a[(l+r)>>1];
	int i=l,j=r;
	do{
		while(a[i]mid) j--;
		if(i<=j)
		{
			swap(a[i],a[j]);
			i++;
			j--;
		}
	}while(i<=j);
	if(l
//课本上的代码...考试用
#include"dataList.h"
template
void QuickSort(dataList&L,const int left,const int right)
{
	if(left
int dataList::Partition(const int low,const int high)
{
	int pivotpos=low;Elementpivot=Vector[low];
	for(int i=low+1;i<=high;i++)
	{
		if(Vector[i]

(三)时间复杂度分析
O(nlogn)

二、堆排序

(一)原理:小根堆保证父亲小于两个儿子,大根堆保证父亲大于两个儿子。
(二)代码

//堆排 
#include
#include
#define N 1000009
using namespace std;

int n,tot;
int d[N];

void up(int x)
{
	if(x==0) return;
	if(d[x]tot) return;
	if(x*2+1>tot) nxt=x*2;
	else nxt=d[x*2]d[nxt])
	{
		swap(d[x],d[nxt]);
		down(nxt);
	}
}
 
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		d[++tot]=x;
		up(tot);
	}
	for(int i=1;i<=n;i++)
	{
		cout<

#define DefaultSize 10;
template
struct Element
{
	T key;
	field otherdata;
	Element& operator = (Element&x)
	{
		key=x.key;
		otherdata=x.otherdata;
	}
	bool operator >= (Element&x){return key>=x.key;}
	bool operator < (Element&x){return key
class MaxHeap{
	public:
		MaxHeap(int sz=DefaultSize);//构造函数,建立空堆
		MaxHeap(Elementarr[],int n);//构造函数
		~Maxheap(delete []heap;)//析构函数
		bool Insert(Element&x);//将x插入到最大堆中
		bool Remove(Element&x);//删除堆顶上的最大元素
		bool IsEmpty() const{return currentSize==0;}
		bool IsFull() const{return currentSize==maxHeapSize;}
	private:
		Element*heap;
		int currentSize;
		int maxHeapSize;
		void siftDown(int start,int m);//从start到m自顶向下调整
		void siftUp(int start);         //从start到0自底向上调整
		Swap(const int i,const int j)
		{
			Elementtmp=heap[i];
			heap[i]=heap[j];
			heap[j]=tmp;
	    }
};

template
void maxHeap::siftDown(const int start,const int m)
{
	int i=start;int j=2*i+1;
	Elementtemp=heap[i];//暂存子树根节点
	while(j<=m)                   //检查是否到最后 
	{
		if(j=heap[j]) break;
		else{
			heap[i]=heap[j];
			i=j;j=2*j+1;
		} 
	} 
	heap[i]=temp;
};
#include"maxheap.h"
template
void HeapSort(maxHeap&H)
{
	for(int i=(currentSize-2)/2;i>=0;i--) siftDown(i,currentSize-1);
	//将表转换成堆
	for(int i=currentSize-1;i>=0;i--)
	{
		Swap(0,i);siftDown(0,i-1);
	} 
};

(三)时间复杂度
O(nlogn)

三、希尔排序

(一)原理:将数组下标相差gap的元素进行插入排序,然后不断缩小gap。
(二)代码

#include
#include
#include
#define N 100009
using namespace std;

int n;
int a[N]; 

void ShellSort()
{
	int j,temp,d;
	d=n/2;
	while(d>0)
	{
		for(int i=d+1;i<=n;i++)
		{
			temp=a[i];
			j=i-d;
			while(j>0&&a[j]>temp)
			{
				a[j+d]=a[j];
				j=j-d;
			}
			a[j+d]=temp;
		}
		d/=2;
	}
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	ShellSort();
	for(int i=1;i<=n;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
} 

#include"dataList.h"
template
void Shellsort(dataList&L,const int left,const int right)
{
	int i,j,gap=right-left+1;
	Elementtemp;
	do{
		gap=gap/3+1;
		for(i=left+gap;i<=right;i++)
		{
			if(L[i]=left&&temp1);
};

(三)时间复杂度
O(n^(1.3—2))

四、插入排序

(一)每一个元素与其前面已经有序的元素比较,插入到合适的位置。
(二)代码
(1)直接插入排序

#include"dataList.h"
template
void InsertSort(dataList&L,const int left,const int right)
{
	Elementtemp;int i,j;
	for(int i=left+1;i<=right;i++) //i是当前准备要插入的元素,1---i-1都是有序的 
	{                                         //一共需要插入n-1 
		if(L[i]=left&&temp
#include
#include
#include
#include
#define N 1000009
using namespace std;

int n;
int a[N];

void InsertSort(int a[],int left,int right)
{
	int temp,j; 
	for(int i=left+1;i<=right;i++)
	{
		if(a[i]=left&&a[j]>temp);
			a[j+1]=temp;
		}	  
	}
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	InsertSort(a,1,n);
	for(int i=1;i<=n;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
} 

 

(2)折半插入排序

#include"dataList.h"
template
void BinaryInsertSort(dataList&L,const int left,const int right)
{
	Elementtemp;int i,low,high,middle,k;
	for(int i=left+1;i<=right;i++)  //i为当前插入元素,一共插入n-1次,left---i-1都为有序的 
	{
		temp=L[i];low=left;high=i-1;          //在[left,high]区间内寻找大于a[i]的最小元素 
		while(low<=high)
		{
			middle=(low+high)/2;
			if(temp=low;k--) L[k+1]=L[k];  //[low,i-1]后移 
		L[low]=temp;                    //low就是插入的位置 
	}
} 




#include
#include
#include
#define N 100009
using namespace std;

int n;
int a[N];

void BinaryInsertSort(int a[],int left,int right)
{
	int i,low,high,middle,k,temp;
	for(int i=left+1;i<=right;i++)
	{
		temp=a[i];low=left;high=i-1;
		while(low<=high)
		{
			middle=(low+high)/2;
			if(a[middle]>temp)
			{
				high=middle-1;
			}else low=middle+1;
		}
		for(k=i-1;k>=low;k--) a[k+1]=a[k];
		a[low]=temp;
	}
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	BinaryInsertSort(a,1,n);
	for(int i=1;i<=n;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
} 

(三)时间复杂度
(1)直接插入 O(n^2)
(2)折半插入 O(n^2)

五、归并排序

(一)原理:递归减少区间大小,然后再合并。
(二)代码

//归并排序 
#include
#include
#include
using namespace std;

int n,a[100009],tmp[100009];

void merge_sort(int l,int r){
    if(l==r)return;
    int mid=(l+r)>>1;
    merge_sort(l,mid);
    merge_sort(mid+1,r);
    int ii=l,jj=mid+1,k=l;
    while(ii<=mid&&jj<=r){
        if(a[ii]
#include"dataList.h"
template
void merge(dataList&L1,dataList&L2,const int left,const int mid,const int right)
{
	for(int k=left;k<=right;k++) L2[k]=L1[k];
 	int s1=left,s2=mid+1,t=left;
 	while(s1<=mid&&s2<=right)//s1和s2是检测指针,t是存放指针 
 	{
 		if(L2[s1]<=L2[s2]) L1[t++]=L2[s1++];
		 else L1[t++]=L2[s2++]; 
	}
	while(s1<=mid) L1[t++]=L2[s1++];
	while(s2<=right) L1[t++]=L2[s2++];
}

void mergeSort(dataList&L,dataList&L2,int left,int right)
{
	if(left>=right) return;
	int mid=(left+right)/2;
	mergeSort(L,L2,left,mid);
	mergeSort(L,L2,mid+1,right);
	merge(L,L2,left,mid,right); 
}

(三)时间复杂度
O(n log n)

六、选择排序

(一)原理: 每次选择没被选择元素中最小的放到已经排序的序列里。
(二)代码


//选择排序 
#include"dataList.h"
template
void SelectSort(dataList&L,const int left,const int right)
{
	for(int i=left;i
#include
#include
#define N 1000009
using namespace std;

int n,a[N];

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i

(三)时间复杂度
O(n^2)

七、冒泡排序

(一)原理:相邻元素不停交换,每次都会有一个最小的被挤到序列的一端。
(二)代码

//冒泡排序 
#include
#include
#define N 100009
using namespace std;

int n;
int a[N];

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;ia[j+1]) swap(a[j],a[j+1]);
		}
	}
	for(int i=1;i<=n;i++) printf("%d ",a[i]);
	return 0;
} 

(三)时间复杂度
O(n^2)

第一次用markdown....
整理太费时间了...不考的我下次不整了...

你可能感兴趣的:(【数据结构】排序)