数据结构 各种排序方法总结(c++)

 

(修正:快速排序的空间复杂度为O(log2n))

1.时间复杂度为O(N2)

#include<iostream>
using namespace std

//初始序列 3 5 1 2 4 
//升序 
//冒泡排序
void bubbleSort(int a[],int n){
	bool flag=true; 
	for(int i=1;i<n&&flag;i++){
		flag=false;
		for(int j=0;j<n-i;j++)
		if(a[j]>a[j+1]){
			int temp=a[j];
			a[j]=a[j+1];
			a[j+1]=temp;
			flag=true;
		}
		
	}
}
//评价: 
//时间复杂度 O(n2) 空间复杂度O(1) 
 //最好时间复杂度是O(n) 是一种稳定的排序算法
 //时间复杂度与初始状态有关系 


//选择排序
void selectSort(int a[],int n){
	for(int i=0;i<n-1;i++){
		for(int j=0;j<n-i;j++){
			if(a[j]>a[max_int])
			max_int=j;
		}
		if(max_int!=n-i){
		
		int temp=a[max_int];
		a[max_int]=a[n-i];
		a[n-i]=temp;
	   }
	}
} 
//评价:
//最好时间复杂度O(n2) 
//是一种不稳定的排序算法,例如当存在重复的数时

//直接插入排序(数组)
void insertSort(int a[],int n){
	for(int i=1;i<n;i++){
		int insert_loc=i;
		int temp=a[i];
		while(insert_loc!=0&&temp<a[insert_lco]){
		a[insert_loc]=a[insert_loc-1]
		--insert_loc;
	}
	a[intsert_loc]=temp;
	}
} 
//评价:
//稳定排序算法
//与初始状态有关,最好O(N) 最坏O(n2) 


//直接插入排序(链表)
void insertSort(node* h){
	//默认是有头结点的单链表
	if(h==NULL||h->next==NULL||h->next->next==NULL)
	return;
	node* p=h;
	node*q =h->next;//工作指针
	node* t=q->next;//待排链表表头
	q->next=NULL;
	
	while(t!=NULL){
		p=h;
		q = h->next;
		while(q->val<t->val&&q->next!-NULL){
			q=q->next;
			p=p->next;
		}
		node* temp=t->next;
		t->next=NULL;
		if(q->val>t->val){
			p->next=t;
			t->next=q;
		}
		else
		q->next=t;
		t=temp;
		
	} 
	 
} 
//评价:
//稳定排序算法
//与初始状态有关,最好O(N)逆序 最坏O(n2)正序
//空间复杂度 O(1) 

 

int main(){
	return 0;
}

2.时间复杂度为O(n log n)

#include<iostream>
using namespace std

//初始序列 3 5 1 2 4 
//升序 
//归并排序
void merge(int a[],int n,int b[], int m,int c[]){//二路归并 
	
	int i=0,j=0,k=0;
	while(i<n&&j<m){
		if(a[i]<b[j])
		{
			c[k]=a[i];
			++k;++i;
		}
		else{
			c[k]=b[j];
			++j;++k;
		}	
	}
	while(i<n){
		c[k]=a[i];
			++k;++i;
	}
	while(j<m){
		c[k]=b[j];
			++j;++k;
	}
} 

void mergeSort(vector<int> &a,int l,int r){
	if(l<r){
		int mid=(l+r)/2;
		mergeSort(a,l,mid);
		mergeSort(a,mid+1,r);
		merge(a,l,mid,mid+1,r);
	}
}
 //评价:
 //与初始状态无关 时间复杂度O(nlogn)
 //空间复杂度 O(logn) (使用栈的数量)  算法是稳定的
 
 //堆排序
 #include<iostream>
#include<vector>
using namespace std;
 
// 递归方式构建大根堆(len是arr的长度,index是第一个非叶子节点的下标)
void adjust(vector<int> &arr, int len, int index)
{
    int left = 2*index + 1; // index的左子节点
    int right = 2*index + 2;// index的右子节点
 
    int maxIdx = index;
    if(left<len && arr[left] > arr[maxIdx])     maxIdx = left;
    if(right<len && arr[right] > arr[maxIdx])     maxIdx = right;
 
    if(maxIdx != index)
    {
        swap(arr[maxIdx], arr[index]);
        adjust(arr, len, maxIdx);
    }
 
}
 
// 堆排序
void heapSort(vector<int> &arr, int size)
{
    // 构建大根堆(从最后一个非叶子节点向上)
    for(int i=size/2 - 1; i >= 0; i--)
    {
        adjust(arr, size, i);
    }
 
    // 调整大根堆
    for(int i = size - 1; i >= 1; i--)
    {
        swap(arr[0], arr[i]);           // 将当前最大的放置到数组末尾
        adjust(arr, i, 0);              // 将未完成排序的部分继续进行堆排序
    }
}
 
int main()
{
    vector<int> arr = {8, 1, 14, 3, 21, 5, 7, 10};
    heapSort(arr, arr.size());
    for(int i=0;i<arr.size();i++)
    {
        cout<<arr[i]<<endl;
    }
    return 0;
}

//堆排序 不稳定


//快速排序 (最快的排序)
//(最慢的是选择排序)

void quickSort(vector<int> &a,int left,int right){
	if(left<right){
		int p=position(a,left,right);
		quickSort(a,left,p-1);
		quickSort(a,p+1,right);
	}
}
int position(vector<int> &a,int left,int right){
 int loc = left;
 while(left<right){
 	while(left<right&&a[right]>a[loc])
 	--right;
 	swap(a,loc,right);
 	loc=right;
 	while(left<right&&a[left]<a[loc])
 	++left;
 	swap(a,loc,left);
 	loc=left;
 }
 return loc;
}



 

3. 希尔排序,基数排序,计数排序



//希尔排序

// 希尔排序.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
 
 
#include<iostream>
#include<string>
using namespace std;
void shellSort(int a[],int length);
int main()
{
	int array[]={3,7,1,5,4};
	int length=sizeof(array)/sizeof(int);
 
	cout<<"before sort"<<endl;
	for(int i=0;i<length-1;i++)
	{
		cout<<array[i]<<' ';
	}
	cout<<array[length-1]<<endl;
 
	shellSort(array,sizeof(array)/sizeof(int));
	cout<<"after sort"<<endl;
	for(int i=0;i<length-1;i++)
	{
		cout<<array[i]<<' ';
	}
	cout<<array[length-1]<<endl;
	return 0;
}
 
void shellSort(int a[],int length)
{
	int step;
	step=length/2;
	if(step%2==0)
	{
		step++;
	}
	while(step>0)
	{
	for(int j=step;j<length;j++)
	{
		int temp=a[j];
		int i=j-step;
		while(i>=0&&a[i]>temp)
		{
			a[i+step]=a[i];
			i=i-step;
		}
		if(i!=j-step)
		
			a[i+step]=temp;
		
	}
	if(step==1)break;
	step=step/2;
	if(step%2==0)
		step++;
 
	}
} 
 
//不稳定算法,时间复杂度是步长
//与初始状态有关 
// 

//基数排序
/**
* name:基数排序
* time:15/8/16 15:00
* environment: ubuntu 14.04, sublime text 3
*/
#include <iostream>
using namespace std;
 
/*
* 打印数组
*/
void printArray(int array[],int length)
{
	for (int i = 0; i < length; ++i)
	{
		cout << array[i] << " ";
	}
	cout << endl;
}
/*
*求数据的最大位数,决定排序次数
*/
int maxbit(int data[], int n) 
{
    int d = 1; //保存最大的位数
    int p = 10;
    for(int i = 0; i < n; ++i)
    {
        while(data[i] >= p)
        {
            p *= 10;
            ++d;
        }
    }
    return d;
}
void radixsort(int data[], int n) //基数排序
{
    int d = maxbit(data, n);
    int tmp[n];
    int count[10]; //计数器
    int i, j, k;
    int radix = 1;
    for(i = 1; i <= d; i++) //进行d次排序
    {
        for(j = 0; j < 10; j++)
            count[j] = 0; //每次分配前清空计数器
        for(j = 0; j < n; j++)
        {
            k = (data[j] / radix) % 10; //统计每个桶中的记录数
            count[k]++;
        }
        for(j = 1; j < 10; j++)
            count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶
        for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
        {
            k = (data[j] / radix) % 10;
            tmp[count[k] - 1] = data[j];
            count[k]--;
        }
        for(j = 0; j < n; j++) //将临时数组的内容复制到data中
            data[j] = tmp[j];
        radix = radix * 10;
    }
}
 
int main()
{
	int array[10] = {73,22,93,43,55,14,28,65,39,81};
	radixsort(array,10);
	printArray(array,10);
	return 0;
}
 
//结果
//14 22 28 39 43 55 65 73 81 93  

//时间复杂度与初始状态没有关系  O(r*(排序算法)) 
//稳定排序

//计数排序
#include <iostream>
#include <stdlib.h>
using namespace std;
 
/**********************************************/
/*  计数排序
/*********************************************/
 
void CountingSort(int array[], int n)
{
	int i;
	int largest = array[0];  //设最初最大元素默认是array[0]
	int *temp = new int[n];  //申请一个n个int元素的数组内存
 
	for (i = 1; i < n; i++)
	{
		if (largest < array[i])  //找出最大元素
		{
			largest = array[i];
		}
	}
 
	int *count = new int[largest + 1];  //申请一个[largest+1]个int元素的数组内存
	for (i = 0; i <= largest; i++)
	{
		count[i] = 0;  //初始化
	}
 
	for (i = 0; i < n; i++)
	{
		count[array[i]]++;  //计算array数组每个元素出现的次数
	}
 
	for (i = 1; i <= largest; i++)
	{
		count[i] = count[i - 1] + count[i];  //count数组元素出现次数的累加
	}
 
	for (i = n - 1; i >= 0; i--)
	{
		temp[count[array[i]] - 1] = array[i];  //将array[]数组的元素赋给已经排好位置的temp[]数组
		count[array[i]]--;  //数组元素的总次数减少
	}
 
	for (i = 0; i < n; i++)
	{
		array[i] = temp[i];  //将排好顺序的元素赋给array[]数组
	}
 
	delete[] count;  //释放内存
	count = NULL;
	delete[] temp;  //释放内存
	temp = NULL;
}
 
 
int main(void)  //主程序
{
	const int n = 6;  //数组元素的数量
	int array[n];
	cout << "请输入6个整数:" << endl;
	for (int i = 0; i < n; i++)
	{
		cin >> array[i];
	}
 
	cout << endl;  //换行
 
	CountingSort(array, n);  // 调用CountingSort函数  进行排序
 
	cout << "由小到大的顺序排列后:" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << "Array" << "[" << i << "]" << " = " << array[i] << endl;
	}
 
	cout << endl << endl;  //换行
 
	system("pause");  //调试时,黑窗口不会闪退,一直保持
	return 0;
} 





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值