数据结构与算法总结

排序

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int zero=-1,one=0,two=nums.size();
        while(one<two){
            if(nums[one]==0)
                swap(nums[++zero],nums[one++]);
            else if(nums[one]==2)
                swap(nums[--two],nums[one]);
            else 
                one++;
        }
        return;
    }
};
  • 冒泡排序:
void bubblesort(vector<int> &arr){
	int len=arr.size();
	for(int i=0;i<len-1;i++){
		int flag=0;
		for(int j=0;j<len-i-1;j++){
			if(arr[j]>arr[j+1]){
				flag=1;
				swap(arr[j],arr[j+1]);
			}
		}
		if(!flag)
			break;
	}
}
  • 选择排序:
void selectsort(vector<int> &arr){
	int len=arr.size();
	for(int i=0;i<len-1;i++){
		int minpos=i;
		for(int j=i+1;j<len;j++){
			if(arr[j]<arr[minpos])
				minpos=j;
		}
		if(minpos!=i)
			swap(arr[minpos],arr[i]);
	}
}
  • 插入排序:
void insertsort(vector<int> &arr){
	int len=arr.size();
	for(int i=1;i<len;i++){
		int tmp=arr[i],j;
		for(j=i-1;j>=0&&tmp<arr[j];j--){
			arr[j+1]=arr[j];
		}
		arr[j+1]=tmp;
	}
}
  • 希尔排序:插入排序的改进版,间隔的递增序列满足3n+1
void shellsort(vector<int> &arr){
	int len=arr.size(),gap=1;
	while(gap*3+1<len)
		gap=gap*3+1;
	while(gap>=1){
		for(int i=gap;i<len;i++){
			int tmp=arr[i],j;
			for(j=i-gap;j>=0&&tmp<arr[j];j-=gap){
				arr[j+gap]=arr[j];
			}
			arr[j+gap]=tmp;
		}
		gap/=3;
	}
}
  • 归并排序
void merge(vector<int> &arr,int left,int mid,int right){
	int p=left,q=mid+1,i=0;
	vector<int> tmp(right-left+1,0);
	while(p<=mid&&q<=right){
		if(arr[p]<=arr[q])
			tmp[i++]=arr[p++];
		else
			tmp[i++]=arr[q++];
	}
	while(p<=mid)
		tmp[i++]=arr[p++];
	while(q<=right)
		tmp[i++]=arr[q++];
	for(int j=left;j<=right;j++)
		arr[j]=tmp[j-left];
}
void mergesort(vector<int> &arr,int left,int right){	
	if(left>=right)
		return;
	else{
		int mid=(right-left)/2+left;
		mergesort(arr,left,mid);
		mergesort(arr,mid+1,right);
		merge(arr,left,mid,right);
	}	
}
  • 快速排序:
void quicksort(vector<int> &arr,int left,int right){	
	if(left>=right)
		return;
	else{
		int low=left,high=right,pivot=arr[low];
		while(low<high){
			while(low<high&&arr[high]>=pivot)
				high--;
			if(low<high)
				arr[low++]=arr[high];//high不要减1了,要将前面的数字摆上来
			while(low<high&&arr[low]<pivot)
				low++;
			if(low<high)
				arr[high--]=arr[low];//low不要加1了,后面的数字要摆上来
		}
		arr[low]=pivot;
		quicksort(arr,left,low-1);
		quicksort(arr,low+1,right);
	}	
}
  • 堆排序:先构建堆,然后进行n-1次堆顶元素与最后一个元素的交换。

     上浮法建堆:
     	无序数组建立堆最直接的方法是从左到右遍历数组进行上浮操作。
     	
     下沉法建堆:
     	一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个节点都已经是堆有序,那么进行下沉操作可以使得这个节点为根节点的堆有序。
     	叶子节点不需要进行下沉操作,可以忽略叶子节点的元素,因此只需要遍历一半的元素即可。
    
     交换并下沉:
     	建好堆之后进行n-1次堆顶元素与最后一个元素的交换,每次交换之后需要从堆顶进行下沉操作维持堆的有序状态。
    
#include<bits/stdc++.h>
using namespace std;
//大顶堆 
class heap{
	private:
		vector<int> arr;
		int len;
	public:
		heap(vector<int> a):arr(a),len(a.size()-1){}
		//上浮 
		void up(int k){
			while(k/2>0){
				int p=k/2;
				if(arr[p]<arr[k])
					swap(arr[p],arr[k]);
				k=p;
			}
		}
		//下沉,最重要的函数(必会)
		void down(int k){
			while(2*k<=len){
				int j=2*k;
				if(2*k+1<=len&&arr[2*k+1]>arr[j])
					j=2*k+1;
				if(arr[j]<=arr[k])
					break;
				swap(arr[k],arr[j]);
				k=j;
			}
		}
		void CreateHeap(){
			//下沉调整,只用遍历一半 
			for(int i=len/2;i>=1;i--)
				down(i);
			//上浮调整 
			//for(int i=1;i<=len;i++)
			//	up(i);
		}
		void HeapSort(){
			CreateHeap();
			for(int i=1;i<arr.size()-1;i++){
				swap(arr[1],arr[len]);
				len--;
				down(1);
			}
		}
		void print(){
			for(int i=1;i<arr.size();i++)
				cout<<arr[i]<<" ";
		}
};

int main(){
	vector<int> arr;
	srand(time(NULL));
	arr.push_back(-1);
	for(int i=0;i<10;i++)
		arr.push_back(rand()%100);
	heap target(arr);
	target.HeapSort();
	target.print();
}

并查集

  1. make-set:把每个结点的父结点置为自身,相当于自己是一个集合
  2. find:向上找到最终父结点
  3. union:让一个最终父结点指向另外一个最终父结点实现合并
  4. 统计有多少个连通分量:计算有多少个结点的parent为自身即可。

优化策略:并查集的两种启发式策略优化

例题:


链表

其它

面试宝典

刷题

还是得靠刷题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值