专题1--排序算法

参考:https://www.cnblogs.com/fnlingnzb-learner/p/9374732.html

一、排序算法分析

序号排序方法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
01插入排序O(n2)O(n2)O(n)O(1)稳定
02希尔排序O(n1.3)O(n2)O(n)O(1)不稳定
03选择排序O(n2)O(n2)O(n2)O(1)不稳定
04堆排序O(nlogn)O(nlogn)O(nlogn)O(1)不稳定
05冒泡排序O(n2)O(n2)O(n)O(1)稳定
06快速排序O(nlogn)O(n2)O(nlogn)O(nlogn)不稳定
07归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定

二、算法实现

01 插入排序

class Solution{
public:
	void InsertSort(vector<int>& nums){
		if(nums.size() < 2 ) return;
		int i, j;
		for(int i = 0; i < nums.size(); i++){
			for(int j = i; j > 0; j--){
				if(nums[j] < nums[j-1]) swap(nums[j], nums[j-1]);
				else break;
			}
		}
		return;
	}
}

02 希尔排序

class Solution{
public:
	void ShelltSort(vector<int>& nums){
		int n = nums.size();
		if(n < 2 ) return;
		for(int div = n / 2; div >= 1; div /= 2){ //分为几组
			for(int k = 0; k < div; k++){ //每组比较
				for(int i = div + k; i < n; i+= div){ //控制步长
					for(int j = i; j > k; j-= div){  //从后往前比较
						if(nums[j] > nums[j-div]) 
							swap(nums[j],nums[j-div]);

		return;
	}
}

03 选择排序

class Solution{
public:
	void SelectSort(vector<int>& nums){
		int len = nums.size();
		if(len < 2 ) return;
		int min, i,j;
		for(i = 0; i < len - 1; i++){
			min = i;
			for(j = i; j < len; j++)
				if(nums[j] < nums[min]) min = j;
			swap(nums[i],muns[min]);
		}
		return;
	}
}

04 堆排序

三步法:
1、创建堆;
2、交换数据;
3、向下调整。
最大堆sort之后:数据从小到大排序

class Solution{
public:
	
	void adjustheap(vector<int>& nums, int node, int len){
		int index = node;
		int child = 2 * index + 1; //因为第一个编号是0
		while(child < len){
			if(child+1 < len && nums[child] < nums[child + 1]) child++;
			if(nums[child] < nums[index]) break;
			swap(nums[child], nums[index]);
			index = child;
			child = index * 2 + 1;
		}
	}
	
	void makeheap(vector<int>& nums, int len){
		for(int i = len / 2; i >= 0; i--){
			adjustheap(nums,i,len);
		}
	}
	
	void heapSort(vector<int>& nums){
		int len = nums.size();
		makeheap(nums,len);
		for(int i = len - 1; i >= 0; i--){
			swap(nums[0],nums[i]);
			adjustheap(nums,0,i);
		}
		return nums;
	}
}

05 冒泡排序

class Solution{
public:
	void bubbleSort(vector<int>& nums){
		int len = nums.size();
		if(len < 2 ) return;
		//i是次数,j是下标
		for(i = 0; i < len-1; i++){
			for(j = 0; j < len-1-i; j++)
				if(nums[j] > nums[j+1]) 
					swap(nums[j],muns[j+1]);
		}
		return;
	}
}

06 快速排序

递归实现

class Solution{
public:
	void __quicksort(vector<int>& nums, int left, int right){
		if(nums.size() == 0) return;
		if(left >= right) return;
		
		//防止有序数组降低效率
		srand((unsigned)time(NULL));
		int len = right - left;
		int kindex = rand() % (len + 1) + left;//随机选取基准数
		swap(nums[index],nums[left]);
		
		int key = nums[left], i = left, j = right;
		while(i < j){
			while(nums[j] >= key && i < j) j--;
			if(i < j) nums[i] = nums[j];
			while(nums[i] < key && i < j) i++;
			if(i < j) nums[j] = nums[i]; 
 		}
		
		h[i] = key;
		__quicksort(nums,left,i-1);
		__quicksort(nums,j+1,right);//这样的一个好处,去掉相等的key
}
	void quickSort(vector<int>& nums){
		int left = 0, right = nums.size()-1;
		__quicksort(nums,left, right);
	}
}

非递归实现

class Solution{
public:
	void partition(vector<int>& nums,int left, int right){
		int key = nums[left];
		while(left < right){
			while(nums[right] >= key && left < right) right--;
			if(left < right) nums[left] = nums[right];
			while(nums[left] < key && left < right) left++;
			if(left < right) nums[right] = nums[left];
		}
		nums[left] = key;
		return left;
    }
	void __quicksort(vector<int>& nums, int left, int right){
		//手动利用栈来存储每次快排的起点
		//栈非空时循环获取中轴入栈
		stack <int> s;
		if(left < right){
			int index = partition(nums, left, right);
			if(index -1 > left){ //确保左分区存在
				s.push(left);
				s.push(index-1);
			}
			if(index + 1 < right){ //确保右分区存在
				s.push(index+1);
				s.push(right);
			}
			while( !s.empty()){
				int r = s.top(); s.pop();
				int l = s.top(); s.pop();
				
				index = partition(nums,l,r);
				if(index - 1 > l){
					s.push(l);
					s.push(index-1);
				}	
				if(index + 1 < r){
					s.push(index +1);
					s.push(r);
				}
			}
		}	
}
	void quickSort(vector<int>& nums){
		int left = 0, right = nums.size()-1;
		__quicksort(nums,left, right);
	}
}

07 归并排序

class Solution{
public:
	void __merge(vector<int>& nums, int left, int mid, int right){
		//将nums[left...mid]和nums[mid+1...right]两部分进行归并
		int tem[right-left+1];
		//赋初值
		for(int i = left; i <= right; left++){
			tem[i-left] = nums[i];
		}
		int i = left, j = mid + 1;
		for(int k = left; k <= r; k++){
			 if(i > mid){ nums[k] = tem[j-left]; j++;}
			 else if( j > r){nums[k] = tem[i-left]; i++;}
			 else if(tem[i-left] < tem[j-left]){
			 	nums[k] = tem[i-left]; 
			 	i++;
			 }
			 else {nums[k] = tem[right-l]; j++;}
		}
	}
	void __mergesort(vector<int>& nums, int left, int right){
		if(left >= right) return;
		int mid = (left + right) / 2;
		__mergesort(nums, left, mid);
		__mergesort(nums,mid + 1, right);
		__merge(nums, left, mid, right);	
	}
	void mergeSort(vector<int>& nums){
		__mergesort(nums, 0, nums.size()-1);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值