专题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);
	}
}

你可能感兴趣的:(毕业笔试/面试记录,leetcode)