D
G
O
L

自制考研数据机构常考代码

数据结构

顺序表

快慢指针删除重复元素

#include<bits/stdc++.h>
using namespace std;
struct sqllist{
	vector<int>res;
};
typedef struct sqllist sqllist;
void delete_duplicate(sqllist&s){
	if(s.res.size()==0){
		//TODO
		return;
	}
	//无论是否重复,第一个元素肯定保持不动,所以下标从1开始
	int slow=1,fast=1;
	while(fast<s.res.size()){
		//TODO
		if(s.res[fast]!=s.res[fast-1]){
			//TODO
			//fast和slow差一,当fast和slow所指元素相同,fast,一直右移,直到找到不是fast-1,所指元素
			//不把fast-1换成slow,是因为考虑下标0
			s.res[slow]=s.res[fast];
			slow++;
		}
		fast++;
	}
	s.res.resize(slow);//重新设置一下长度
}

int main(){
	//双指针实现删除有序数组中的重复元素
	sqllist s;
	s.res={1,2,3,3,4,4,5};
	delete_duplicate(s);
	for(int num:s.res){cout<<num<<" ";}
	return 0;
}

合并两个顺序表

//2.2.3.07合并两个顺序表
#include<bits/stdc++.h>
using namespace std;
struct sqllist{
	vector<int>sql;
	int lengh;
	sqllist(){}
	sqllist(int k):lengh(k),sql(k){}
};
typedef struct sqllist sqllist;
sqllist mer(vector<int>&s1,vector<int>&s2){
	sqllist res(s1.size()+s2.size());
	int k=0,i=0,j=0;
	while(i<s1.size()&&j<s2.size()){
		//TODO
		if(s1[i]<=s2[j]){
			//TODO
			res.sql[k]=s1[i];
			i++;
			k++;
		}else{
			res.sql[k]=s2[j];
			j++;
			k++;
		}
	}
	//会有剩下的
	while(i<s1.size()){
		//TODO
		res.sql[k]=s1[i];
		i++;
		k++;
	}
	while(j<s2.size()){
		//TODO
		res.sql[k]=s2[j];
		j++;
		k++;
	}
	return res;
}
int main(){
	sqllist s1;
	for(int i=0;i<=10;i=i+2){
		//TODO
		s1.sql.push_back(i);
	}
	sqllist s2;
	for(int i=1;i<=10;i=i+2){
		//TODO
		s2.sql.push_back(i);
	}

	sqllist sres= mer(s1.sql,s2.sql);
	for(int num:sres.sql){cout<<num<<" ";}
	return 0;
}

折半查找

#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vet;
void change_or_insert(vet&v,int x){
	int i=0,j=v.size()-1;
	int mid=0;
	while(i<=j){
		//TODO
		mid=(i+j)/2;
		if(v[mid]==x){
			//TODO
			break;
		}else if(v[mid]<x){
			//TODO
			i=mid+1;
		}else{
			j=mid-1;
		}
	}
	if(v[mid]==x&&mid!=v.size()-1){
		//TODO
		swap(v[mid],v[mid+1]);
	}
	if(i>j){
		//TODO
		i=0;

		while(i<v.size()){
			//TODO
			if(v[i]<x){
				//TODO,不可能出现=x
				i++;
				break;//找到x的位置
			}
		}
		v.push_back(v[v.size()-1]);
		for(int j=v.size()-2;j>=i;j--){
			//TODO
			v[j+1]=v[j];
		}
		v[i]=x;
	}
}
int main(){
	vet v{1,3,4,5,6,7,8,9,10};
	change_or_insert(v,2);
	for(int num:v){cout<<num<<" ";}
}

循环迁移

#include<bits/stdc++.h>
using namespace std;
vector<int> left_p(int p,vector<int>&a){
	if(a.size()==0){
		return a;
	}
	vector<int> res;
	for(int i=p;i<a.size();i++){
		//TODO
		res.push_back(a[i]);
	}
	for(int i=0;i<p;i++){
		//TODO
		res.push_back(a[i]);
	}
	return res;
}
int main(){
	vector<int> a{1,2,3,4,5,10,12,13,14,15};
	vector<int>res=left_p(4,a);
	for(int num:res){cout<<num<<" ";}
	return 0;
}

链表

反转链表

//反转链表
#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode* next;
	listnode():data(-1),next(nullptr){}
	listnode(int data):data(data),next(nullptr){}
	listnode(int data,struct listnode*next):data(data),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* mylist;
void print(listnode *l){
	while(l!=nullptr){
		//TODO
		cout<<l->data<<" ";
		l=l->next;
	}
	cout<<endl;
}
listnode * create_list(){
	listnode* p_head=new listnode();
	listnode* p_move=p_head;
	cout<<"请输入链表结点的个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"请输入第"<<i<<"个元素"<<endl;
		int data;
		cin>>data;
		listnode* p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head;
}
listnode * reverse_list(listnode*l){
	//迭代算法
	//每一次循环都需要先记录一下p_move的next,否则修改指针后,next就找不到了
	listnode *p_move=l;
	listnode *pr=nullptr;
	while(p_move!=nullptr){
		//TODO
		listnode *p_move_next=p_move->next;
		p_move->next=pr;
		pr=p_move;
		p_move=p_move_next;
		//助记,三条语句执行顺序是个闭合环
	}
	return pr;

}
int main(){
	listnode* test_list=create_list();
	listnode* res_list=reverse_list(test_list->next);
	print(res_list);
	return 0;
}

合并链表

#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode* next;
	listnode():data(0),next(nullptr){}
	listnode(int x):data(x),next(nullptr){}
	listnode(int x,struct listnode* next):data(x),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* list;
void print(listnode *l){
	while(l!=nullptr){
		cout<<l->data<<" ";
		l=l->next;
	}
}
//合并链表
listnode * merge_list(listnode *l1,listnode *l2){
	listnode *p_head=new listnode(-1);
	listnode *p_move=p_head;
	while(l1!=nullptr&&l2!=nullptr){
		//TODO
		if(l1->data<l2->data){
			//TODO
			p_move->next=l1;
			l1=l1->next;
			p_move=p_move->next;
		}else{
			p_move->next=l2;
			l1=l2->next;
			p_move=p_move->next;
		}
	}
	//最后会有l1或者l2有剩下
	if(l1!=nullptr){
		//TODO
		p_move->next=l1;
	}else{
		p_move->next=l2;
	}
	cout<<endl;
	print(p_head);
	cout<<endl;
	return p_head->next;
}
listnode* create_list(){
	int num=-1;
	//请输入num,输入0,表示完成
	cout<<"请输入个数"<<endl;
	int count=0;

	cin >> count;
	listnode* head=new listnode(-1);
	listnode* p_move=head;
	int i=1;
	while(i<=count){
		cin>>num;
		listnode *p_new=new listnode(num);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return head;
}

int main(){
	//创建两个链表
	listnode* l1=create_list();
	print(l1);
	listnode* l2=create_list();
	cout<<endl;
	print(l2);
	cout<<endl;
	listnode* out=merge_list(l1->next,l2->next);
	print(out);
}

回文链表

//回文列表
#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode* next;
	listnode():data(-1),next(nullptr){}
	listnode(int data):data(data),next(nullptr){}
	listnode(int data,struct listnode*next):data(data),next(next){}
};
listnode * create_list(){
	listnode *p_head=new listnode();
	listnode *p_move=p_head;
	cout<<"请输入链表结点的个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"请输入第"<<i<<"个结点"<<endl;
		int data;
		cin>>data;
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	return p_head;
}
bool is_huiwei(listnode *l){
	//先将元素全都放入数组,然后双指针遍历
	vector<int>test;
	while(l!=nullptr){
		//TODO
		test.push_back(l->data);
		l=l->next;
	}
	if(test.size()%2!=0){
		//TODO
		return false;
	}
	for(int i=0,j=test.size()-1;i<(test.size()/2);i++){
		//TODO
		if(test[i]==test[j]){
			//TODO
			j--;
		}else{
			return false;
		}
	}
	return true;
}
int main(){
    listnode *test=create_list();
	bool hi= is_huiwei(test->next);
	cout<<hi<<endl;
	return 0;
}

二进制链表

#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode* next;
	listnode():data(-1),next(nullptr){}
	listnode(int x):data(x),next(nullptr){}
	listnode(int x,struct listnode*next):data(x),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* list;
void print(listnode*l){
	while(l!=nullptr){
		//TODO
		cout<<l->data<<" ";
	}
	cout<<endl;
}
listnode * create_list(){
	listnode *p_head=new listnode();
	listnode *p_move=p_head;
	cout<<"请输入结点的个数"<<endl;
	int counts;
	cin>>counts;
	int i=1;
	while(i<=counts){
		//TODO
		int data;
		cout<<"请输入第"<<i<<"个元素"<<endl;
		cin>>data;
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head;
}
int bi_cal_list(listnode*l){
	int res=0;
	while(l!=nullptr){
		//TODO
		res=res*2+l->data;
		l=l->next;
	}
	return res;
}
int main(){
	listnode *test=create_list();
	int res=bi_cal_list(test->next);
	cout<<res<<endl;
	return 0;
}

链表重合结点

//判断相交链表
#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode* next;
	listnode():data(-1),next(nullptr){}
	listnode(int data):data(data),next(nullptr){}
	listnode(int data,struct listnode*next):data(data),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* list;
void print(listnode *l){
	while(l->next!=nullptr){
		//TODO
		cout<<l->data<<" ";
		l=l->next;
	}
}
listnode * create_list(){
	listnode *p_head=new listnode();
	listnode *p_move=p_head;
	cout<<"请输入链表元素的个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	while(i<=num){
		int data;
		cout<<"请输入第"<<i<<"个元素"<<endl;
		cin>>data;
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head;
}
listnode * create_dup_list(listnode *l,listnode *lnew){
	listnode *p_move=l->next;
	while(p_move->next!=nullptr){
		//TODO
		p_move=p_move->next;
	}
	p_move->next=lnew->next;
	return l;
}
listnode * where_dupnode(listnode *l1,listnode *l2){
	//将l1的点全部加入集合;
	//然后加另一个集合,如果有重结点就返回
	unordered_set<listnode*>listnode_co;
	listnode *p_move=l1;
	while(p_move!=nullptr){
		//TODO
		listnode_co.insert(p_move);
		p_move=p_move->next;
	}
	p_move=l2;
	while(p_move!=nullptr){
		//TODO
		if(listnode_co.count(p_move)!=0){
			//TODO
			return p_move;
		}
		p_move=p_move->next;
	}
	return nullptr;
}
int main(){
	listnode *l1=create_list();
	listnode *l2=create_list();
	listnode *lnew=create_list();
	listnode *l1dup=create_dup_list(l1,lnew);
	listnode *l2dup=create_dup_list(l2,lnew);
	listnode * dupnode=where_dupnode(l1dup->next,l2dup->next);
	if(dupnode==nullptr){
		cout<<"无"<<endl;
	}else{cout<<dupnode->data<<endl;}
	return 0;
}

判断链表是否环状

#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode *next;
	listnode():data(-1),next(nullptr){}
	listnode(int x):data(x),next(nullptr){}
	listnode(int x,struct listnode*next):data(x),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* list;
void print(listnode*l){
	while(l!=nullptr){
		//TODO
		cout<<l->data<<" ";
		l=l->next;
	}
}
listnode * creat_list(){
	listnode *p_head=new listnode(-1);
	listnode *p_move=p_head;
	cout<<"请输入链表结点的个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	while(i<=num){
		cout<<"请输入第"<<i<<"个数"<<endl;
		int data;
		cin>>data;
		//TODO
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head;
}
//构造环链表
listnode * creat_circle(listnode*l){
	listnode *p_move=l->next;
	//请输入尾指针指向第几个位置
	cout<<"请输入尾指针指向第几个位置"<<endl;
	int pos;
	cin>>pos;
	int i=1;
	while(i<pos){
		p_move=p_move->next;
		i++;
	}
	listnode *p_pos=p_move;
	while(p_move->next!=nullptr){
		//TODO
		p_move=p_move->next;
	}
	//cout<<p_move->data<<endl;
	p_move->next=p_pos;
	return l;
}
bool is_circle(listnode*l){
	listnode *p_move=l;
	unordered_set<listnode*>seen;
	int i=1;
	while(p_move->next!=nullptr){
		//TODO
		if(seen.count(p_move)==0){
			//TODO
			seen.insert(p_move);
			p_move=p_move->next;
			i++;
		}else{
			return true;
		}

	}
	return false;
}
int main(){
	listnode *test=creat_list();
	print(test);
	cout<<endl;
	listnode *test1=creat_circle(test);
	//cout<<test1->data<<endl;
	//判断是否有环就是,将链表从头开始访问,同时将访问过的顶点记录来
	//有重复的,就直接返回
	bool res=is_circle(test1->next);
	cout<<res<<endl;
	return 0;

}

删除特定值链表

#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode *next;
	listnode():data(-1),next(nullptr){}
	listnode(int data):data(data),next(nullptr){}
	listnode(int data,struct listnode*next):data(data),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* list;
void print(listnode*l){
	while(l!=nullptr){
		//TODO
		cout<<l->data<<" ";
		l=l->next;
	}
}
listnode * create_list(){
	listnode *p_head=new listnode();
	listnode *p_move=p_head;
	cout<<"请输入结点的个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"输入第"<<i<<"个元素"<<endl;
		int data;
		cin>>data;
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	return p_head;
}
listnode * delete_val(listnode *l,int val){

	if(l==nullptr) return l;//空元素

	//删除第一个顶点需要考虑到头节点的重新指向
	while(l!=nullptr&&l->data==val){
		//TODO
		l=l->next;
	}//这里使用while循环避免了val,val,val,val这种情况
	//删除的不是第一个结点
	listnode *p_move=l;//建立一个移动结点
	while(p_move->next!=nullptr){
		//TODO
		if(p_move->next->data==val){
			//TODO
			p_move->next=p_move->next->next;

		}else{
			p_move=p_move->next;
		}
	}
	return l;

}

int main(){
	listnode *test=create_list();
	test=delete_val(test->next,3);
	print(test);
	return 0;
}

删除重复链表结点

//删除重复链表
#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode* next;
	listnode():data(-1),next(nullptr){}
	listnode(int x):data(x),next(nullptr){}
	listnode(int x,struct listnode*next):data(x),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* list;
void print(listnode *l1){
	while(l1!=nullptr){
		//TODO
		cout<<l1->data<<" ";
		l1=l1->next;
	}

}
listnode * creat_list(){
	int num;
	cout<<"请输入链表的个数"<<endl;
	cin>>num;
	listnode *p_head=new listnode();
	listnode *p_move=p_head;
	int i=1;
	while(i<=num){
		int data;
		cout<<"请输入第"<<i<<"个数"<<endl;
		cin>>data;
		//TODO
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	print(p_head);
	cout<<endl;
	return p_head;
}

listnode * delete_adjacent(listnode *l1){
	if(l1==nullptr) return l1;
	listnode *p_move=l1;
	while(p_move->next!=nullptr){
		//TODO
		//cout<<p_move->data<<" ";
		if(p_move->data==p_move->next->data){
			//TODO
			p_move->next=p_move->next->next;
			//出现这种next->data的情况,终止条件需要修改成next!=null,避免出现空指针还要去访问数值


		}else{
			p_move=p_move->next;
		}

	}

	return l1;
}
int main(){
	listnode *test=creat_list();
	listnode *newtest=delete_adjacent(test->next);//test->next直接开始就是输入
	print(newtest);
	return 0;
}

中间链表

//返回中间链表结点
//设计一个vector<listnode>然后就实现了随机存储
#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode *next;
	listnode():data(-1),next(nullptr){}
	listnode(int data):data(data),next(nullptr){}
	listnode(int data,struct listnode*next):data(data),next(next){}
};
typedef struct listnode listnode;
typedef struct listnode* list;
typedef vector<listnode*> lisv;
listnode* create_list(){
	listnode *p_head=new listnode();
	listnode *p_move=p_head;
	cout<<"请输入链表结点的个数"<<endl;
	int size;
	cin>>size;
	int pos=1;
	while(pos<=size){
		//TODO
		cout<<"请输入第"<<pos<<"个元素"<<endl;
		int data;
		cin>>data;
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		pos++;
	}
	p_move->next=nullptr;
	return p_head;
}
listnode * midnode(listnode *l){
	lisv vl;
	while(l!=nullptr){
		//TODO
		vl.push_back(l);
		l=l->next;
	}
	return vl[vl.size()/2];
}
int main(){
	listnode *test=create_list();
	listnode *res=midnode(test->next);
	cout<<res->data<<endl;
	return 0;
}

保留公共结点

//创建公共元素,并删除多余结点
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node *next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(slist l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l->next;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	int num;
	cout<<"输入结点个数"<<endl;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		int data;
		cout<<"输入第"<<i<<"个数"<<endl;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	return p_head;
}
void dele_get_common(slist&l1,slist&l2){
	list_node *p_move1=l1->next;
	list_node *p_move2=l2->next;
	list_node *p_move=l1;
	l1->next=nullptr;
	while(p_move1!=nullptr&&p_move2!=nullptr){
		//TODO
		if(p_move1->data<p_move2->data){
			list_node *p=p_move1;
			p_move1=p_move1->next;
			free(p);
		}
		else if(p_move1->data>p_move2->data){
			//TODO
			list_node *p=p_move2;
			p_move2=p_move2->next;
			free(p);
		}
		else{
			p_move->next=p_move1;
			p_move1=p_move1->next;
			list_node *p=p_move2;
			p_move2=p_move2->next;
			free(p);
			p_move=p_move->next;//始终指向最后一个结点尾插法
			//删除一个留一个
		}
	}
	//将多余的结点删除
	while(p_move2!=nullptr){
		//TODO
		list_node *p=p_move2;
		p_move2=p_move2->next;
		free(p);
	}
	while(p_move1!=nullptr){
		//TODO
		list_node *p=p_move1;
		p_move1=p_move1->next;
		free(p);
	}
}
int main(){
	slist l1=create();
	display(l1);
	slist l2=create();
	display(l2);
	dele_get_common(l1,l2);
	display(l1);
	return 0;
}

链表暴力匹配

//暴力算法模式匹配链表结构
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node *next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(slist l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	int num;
	cout<<"输入结点个数"<<endl;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"输入第"<<i<<"个数"<<endl;
		int data;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	return p_head;
}
bool is_son(slist&dad,slist&son){
	list_node *p_move_dad=dad->next;
	list_node *p_move_son=son->next;
	list_node *p_move_dadpre=dad;
	list_node *p_move_sonpre=p_move_son;
	while(p_move_dad!=nullptr&&p_move_son!=nullptr){
		//TODO
		if(p_move_son->data==p_move_dad->data){
			//TODO
			p_move_dadpre=p_move_dad;
			p_move_dad=p_move_dad->next;
			p_move_son=p_move_son->next;
		}else{
			//儿子回溯到第一个
			p_move_son=p_move_sonpre;
			//父亲回溯到上次结点的下一个
			p_move_dadpre=p_move_dadpre->next;
			p_move_dad=p_move_dadpre->next;
		}
	}
	//儿子先结束,说明是,否则不是
	if(p_move_son==nullptr) return true;
	else{return false;}
}
int main(){
	slist l1=create();
	display(l1);
	slist l2=create();
	display(l2);
	cout<<is_son(l1,l2);
	return 0;
}

链表插入排序

//单链表插入排序
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node* next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(slist l){
	if(l==nullptr){
		//TODO
		return;

	}
	list_node *p_move=l;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
	return;
}
slist create(){
	int num;
	cout<<"请输入链表结点个数"<<endl;
	cin>>num;
	int i=1;
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	while(i<=num){
		//TODO
		cout<<"请输入第"<<i<<"个数"<<endl;
		int data;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;

	}
	p_move->next=nullptr;
	return p_head;
}
void insert_sort(slist&l){
	//定义三个指针,新链表一个,旧链表一个指向当前要准备插入的,一个指向其后继
	list_node *p=l->next;//拿第一个元素做有序序列,p和p之前都是有序序列
	list_node *r=p->next;//指向p的后继,便于往后移动,
	list_node *f=l;//指向头节点,每次从头节点开始遍历,查找位置,确定位置只能next->data,必须头节点开始
	//开始排序从第二个元素开始
	p->next=nullptr;
	p=r;
	while(p!=nullptr){
		//TODO
		//查找位置
		r=p->next;//记录下一个结点,便于后移

		while(f->next!=nullptr&&f->next->data<p->data){
			//TODO
			//必须把f->next!=nullptr放在前面,避免访问空指针
			f=f->next;
		}
		p->next=f->next;
		f->next=p;
		p=r;
		f=l;//f回溯
	}
}
int main(){
	slist l=create();
	display(l->next);
	insert_sort(l);
	cout<<endl;
	display(l->next);
	return 0;
}

//单链表插入排序改版
//单链表插入排序不同的是,每次查找都是从前往后找,因为没有前驱指针
#include<bits/stdc++.h>
using namespace std;
struct listnode{
	int data;
	struct listnode *next;
	listnode():data(-1),next(nullptr){}
	listnode(int x):data(x),next(nullptr){}
};
typedef struct listnode listnode;
typedef struct listnode* slist;
void create(slist&l){
	listnode *p_move=l;
	cout<<"输入个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"输入结点"<<endl;
		int data;
		cin>>data;
		listnode *p_new=new listnode(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
}
void display(slist l){
	while(l!=nullptr){
		//TODO
		cout<<l->data<<" ";
		l=l->next;
	}
}
//插入排序
void insertsort(slist&l){
	if(l==nullptr){
		//TODO
		return;
	}

	listnode *p_head=l;

	listnode *p_move=l->next;
	listnode *p_movenext=p_move->next;

	p_move->next=nullptr;//防止出现环链
	p_move=p_movenext;
	while(p_move!=nullptr){
		//TODO从第二个元素开始查找位置
		p_movenext=p_move->next;
		p_head=l;
		while(p_head->next!=nullptr&&p_head->next->data<p_move->data){
			//TODO
			p_head=p_head->next;
		}
		p_move->next=p_head->next;
		p_head->next=p_move;


		p_move=p_movenext;
	}
}
int main(){
	slist l=new listnode();
	create(l);
	display(l->next);
	insertsort(l);
	cout<<endl;
	display(l->next);
	return 0;
}

链表查找倒数第k个元素

//单链表找到倒数第k个元素
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node* next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(slist l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l->next;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}

}
slist create(){
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	int num;
	cout<<"输入结点个数"<<endl;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"输入第"<<i<<"个结点"<<endl;
		int data;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	return p_head;
}
int find_k(slist&l,int k){
	list_node *p=l->next;
	list_node *q=l->next;
	int i=1;
	while(p->next!=nullptr){
		//TODO
		if(i<k){
			//TODO
			p=p->next;
			i++;
		}else{

			p=p->next;
			q=q->next;
			i++;
		}
	}
	if(i<=k){
		//TODO
		return 0;
	}
	return q->data;
}
int  main(){
	cout<<"输入k"<<endl;
	int k;
	cin>>k;
	slist l=create();
	display(l);
	cout<<endl;
	cout<<find_k(l,k)<<endl;
}

链表删除唯一最小值

//单链表删除最小值(唯一)
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node *next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(list_node *l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	cout<<"请输入结点个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	while(i<=num){
		//TODO
		int data;
		cout<<"请输入第"<<i<<"个数"<<endl;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head;
}
void delete_min(slist&l){
	list_node *min_node=l->next;
	list_node *min_front=l;
	list_node *p_move=l->next;
	list_node *p_move_front=l;
	while(p_move!=nullptr){
		//TODO
		if(p_move->data<min_node->data){
			//TODO
			min_node=p_move;
			min_front=p_move_front;
		}
		p_move_front=p_move;
		p_move=p_move->next;

	}
	//删除最小值结点
	min_front->next=min_node->next;
	free(min_node);
}
int main(){
	slist l=create();
	display(l);
	delete_min(l);
	display(l->next);
}

链表递增输出

//递增输出结点,并将空间释放,与单链表删除最小值相同,只不过多了层循环和输出
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node* next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(list_node*l){
	if(l==nullptr){
		//TODO
		return;

	}
	list_node *p_move=l;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	cout<<"请输入创建结点个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	while(i<=num){
		//TODO
		int data;
		cout<<"请输入第"<<i<<"个值"<<endl;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	return p_head;
}
void delete_and_out(slist&l){
	while(l->next!=nullptr){
		//TODO
		//只要还有结点,l->next就不是空,这是大循环
		list_node *p_move=l->next;
		list_node *p_move_pre=l;
		list_node *p_min_move=l->next;
		list_node *p_min_pre=l;
		while(p_move!=nullptr){
			//TODO
			if(p_move->data<p_min_move->data){
				//TODO
				p_min_move=p_move;
				p_min_pre=p_move_pre;
				//找到最小值后,移动写不写都行,因为下一次比较,肯定执行else
				//p_move_pre=p_move;
				//p_move=p_move->next;
			}else{
				p_move_pre=p_move;
				p_move=p_move->next;
			}
		}
		cout<<p_min_move->data<<" ";
		p_min_pre->next=p_min_move->next;
		free(p_min_move);
	}

}
int main(){
	slist l=create();
	display(l);
	delete_and_out(l);
	return 0;
}

公共元素创建链表

//公共元素创建链表
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node* next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(slist l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	cout<<"输入结点个数"<<endl;
	int num;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		int data;
		cout<<"输入第"<<i<<"个数"<<endl;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head;
}
slist get_common(slist&l1,slist&l2){
	list_node *p_move1=l1->next;
	list_node *p_move2=l2->next;
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	while(p_move1!=nullptr&&p_move2!=nullptr){
		//TODO
		//有顺序,所以每次小的先移动
		if(p_move1->data<p_move2->data){
			//TODO
			p_move1=p_move1->next;
		}
		else if(p_move1->data>p_move2->data){
			//TODO
			p_move2=p_move2->next;
		}
		else{
			list_node *p_new=new list_node(p_move1->data);
			p_move->next=p_new;
			p_move=p_move->next;
			//同时两指针同时后移
			p_move1=p_move1->next;
			p_move2=p_move2->next;
		}
	}
	return p_head;
}
int main(){
	slist l1=create();
	display(l1);
	slist l2=create();
	display(l2);
	slist l3=get_common(l1,l2);
	display(l3);
	return 0;
}

合并循环链表

//合并两个循环单链表
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node *next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void diplay(slist l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l->next;
	while(p_move!=l){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	int num;
	cout<<"输入结点个数"<<endl;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		int data;
		cout<<"输入第"<<i<<"个数"<<endl;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=p_head;
	return p_head;
}
void merge_list(slist&l1,slist&l2){
	list_node *p_move1=l1->next;
	while(p_move1->next!=l1){
		//TODO
		p_move1=p_move1->next;
	}
	p_move1->next=l2->next;
	list_node *p_move2=l2->next;
	while(p_move2->next!=l2){
		//TODO
		p_move2=p_move2->next;
	}
	free(l2);
	p_move2->next=l1;
}
int main(){
	slist l1=create();
	slist l2=create();
	merge_list(l1,l2);
	diplay(l1);
	return 0;
}

头插法

//头插法,递减序列
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node *next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(slist l){
	if(l==nullptr){
		//TODO
		return ;
	}
	list_node *p_move=l->next;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	int num;
	cout<<"请输入个数"<<endl;
	cin>>num;
	int i=1;
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	while(i<=num){
		//TODO
		int data;
		cout<<"请输入第"<<i<<"个数"<<endl;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head;
}
void merge_reverse(slist&l1,slist&l2){
	list_node *p_move1=l1->next;
	list_node *p_move2=l2->next;
	list_node *p1_next,*p2_next;
	l1->next=nullptr;
	while(p_move1!=nullptr&&p_move2!=nullptr){
		//TODO
		if(p_move1->data<p_move2->data){
			//TODO
			p1_next=p_move1->next;
			p_move1->next=l1->next;
			l1->next=p_move1;
			p_move1=p1_next;
		}else{
			p2_next=p_move2->next;
			p_move2->next=l1->next;
			l1->next=p_move2;
			p_move2=p2_next;
		}
	}
	//最后会有一个剩下
	if(p_move1!=nullptr){
		while(p_move1!=nullptr){
			//TODO
			p1_next=p_move1->next;
			p_move1->next=l1->next;
			l1->next=p_move1;
			p_move1=p1_next;
		}

	}else{
		while(p_move2!=nullptr){
			//TODO
			p2_next=p_move2->next;
			p_move2->next=l1->next;
			l1->next=p_move2;
			p_move2=p2_next;
		}
	}
	free(l2);
}
int main(){
	slist l1=create();
	slist l2=create();
	display(l1);
	cout<<endl;
	display(l2);
	merge_reverse(l1,l2);
	cout<<endl;
	display(l1);
	return 0;
}

递归删除结点

#include<bits/stdc++.h>
#define maxsize 100
using namespace std;
//无头结点可以先头节点创立,然后返回头节点next
struct list_node{
	int data;
	struct list_node *next;
	list_node():data(-1),next(nullptr){}
	list_node(int x):data(x),next(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
void display(list_node *l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l;
	while(p_move!=nullptr){
		//TODO
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
	cout<<endl;
}
slist create(){
	int num;
	cout<<"输入结点个数"<<endl;
	cin>>num;
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"请输入第"<<i<<"个值"<<endl;
		int data;
		cin>>data;
		list_node *p_new =new list_node(data);
		p_move->next=p_new;
		p_move=p_move->next;
		i++;
	}
	p_move->next=nullptr;
	return p_head->next;
}
void recur_delete_X(slist&l,int x){
	//递归跳出条件写在最前面
	if(l==nullptr){
		//TODO
		return;
	}
	//递归操作
	if(l->data==x){
		//TODO
		list_node *p=l;
		l=l->next;
		free(p);
		recur_delete_X(l->next,x);//递归下一层
	}else{
		recur_delete_X(l->next,x);//递归下一层
	}

}
int main(){
	list_node *l=create();
	display(l);
	recur_delete_X(l,4);
	display(l);
}

循环链表对称

//循环双链表表是否对称
#include<bits/stdc++.h>
using namespace std;
struct list_node{
	int data;
	struct list_node *next;
	struct list_node *prior;
	list_node():data(-1),next(nullptr),prior(nullptr){}
	list_node(int x):data(x),next(nullptr),prior(nullptr){}
};
typedef struct list_node list_node;
typedef struct list_node* slist;
//打印循环双链表
void display(slist l){
	if(l==nullptr){
		//TODO
		return;
	}
	list_node *p_move=l->next;
	while(p_move!=l){
		//TODO,当指针循环到头结点,说明遍历完
		cout<<p_move->data<<" ";
		p_move=p_move->next;
	}
}
slist create(){
	list_node *p_head=new list_node();
	list_node *p_move=p_head;
	//循环双链表头节点初始化
	p_head->next=p_head;
	p_head->prior=p_head;
	int num;
	cout<<"输入结点个数"<<endl;
	cin>>num;
	int i=1;
	while(i<=num){
		//TODO
		cout<<"输入第"<<i<<"个数"<<endl;
		int data;
		cin>>data;
		list_node *p_new=new list_node(data);
		p_move->next=p_new;
		p_new->prior=p_move;
		p_new->next=p_head;
		p_head->prior=p_new;
		p_move=p_new;
		i++;
	}
	return p_head;
}
bool is_symmetry(slist&l){
	list_node *p=l->next;//第一个结点
	cout<<p->data<<endl;
	list_node *q=l->prior;//最后一个结点
	cout<<q->data<<endl;
	while(p!=q&&q->next!=p){
		//TODO
		//p!=q,奇数截止
		//q->next!=p,偶数截止
		if(p->data==q->data){
			//TODO
			p=p->next;
			q=q->prior;
		}else{
			return false;
		}
	}
	return true;
}
int main(){
	slist l1=create();
	display(l1);
	cout<<is_symmetry(l1);
	return 0;
}

单调栈实现下一个最大元素

//单调栈只能实现下一个更大的元素
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> arr;
arr next_max(arr&num1,arr&num2){
	stack <int>sta;
	unordered_map<int,int>next_store;
	for(int i=0;i<num2.size();i++){
		//TODO
		while(!(sta.empty())&&sta.top()<num2[i]){
			//TODO
			next_store[sta.top()]=num2[i];
			sta.pop();
		}
		//空的时候,入栈,不为空,但是小于栈顶,也入栈
		sta.push(num2[i]);
	}
	//剩下的就只是-1了;
	while(!sta.empty()){
		//TODO
		next_store[sta.top()]=-1;
		sta.pop();
	}
	arr res;
	for(int i=0;i<num1.size();i++){
		//TODO
		res.push_back(next_store[num1[i]]);
	}
	for(int num:res){cout<<num<<" ";}
	return res;
}
int main(){
	arr num1{4,1,2};
	arr num2{1,3,4,2};
	arr res=next_max(num1,num2);
	return 0;
}

二叉树非递归后序遍历

#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int data):data(data),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
typedef vector<int> arr;
void create_tree(tree&root){
	string ch="";
	cout<<"请按先序输入,以#表示空"<<endl;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;
	}else{
		root=new treenode(stoi(ch));
		//cout<<root->data<<endl;
		create_tree(root->left);
		create_tree(root->right);
	}

}
void post_order(tree&root,arr&a){
	stack<treenode*>stree;
	if(root==nullptr){
		//TODO
		return;
	}
	while(!stree.empty()||root!=nullptr){
		//TODO
		while(root!=nullptr){
			//TODO
			a.push_back(root->data);
			stree.push(root);
			root=root->right;
		}
		//当右子树访问到最后
		root=stree.top();
		stree.pop();
		root=root->left;
	}



}
int main(){
	treenode *root;
	create_tree(root);
	arr a;

	post_order(root,a);
	reverse(a.begin(),a.end());
	for(int num:a){cout<<num<<" ";}
	return 0;
}

二叉树非递归先序遍历

#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode* left;
	struct treenode* right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int data):data(data),left(nullptr),right(nullptr){}
	treenode(int data,struct treenode*left,struct treenode*right):data(data),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
typedef vector<int> arr;
//因为二叉树没有头节点,所以创造时,必须传入参数
void create_tree(tree&root){
	string ch="";
	cout<<"请输入元素按先序序列,#表示空"<<endl;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;//空,就把结点设成空
	}else{
		root=new treenode(stoi(ch));
		create_tree(root->left);
		create_tree(root->right);
	}

	return ;


}
void pre_order(tree&root,arr&a){
	if(root==nullptr){
		return;
	}
	stack<treenode*> stree;
	while(!stree.empty()||root!=nullptr){
		while(root!=nullptr){
			//TODO
			a.push_back(root->data);
			stree.push(root);
			root=root->left;
		}
		root=stree.top();
		stree.pop();
		root=root->right;
		
	}
}
int main(){
	treenode *root=new treenode();
	create_tree(root);
	arr a;
	pre_order(root,a);
	for(int num:a){cout<<num<<" ";}
}

二叉树非递归中序遍历

//二叉树的非递归中序遍历
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(),left(nullptr),right(nullptr){}
	treenode(int data):data(data),left(nullptr),right(nullptr){}
	treenode(int data,struct treenode*left,struct treenode*right):data(data),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
typedef vector<int> arr;
void create_tree(tree &node){
	string ch;
	cout<<"请输入元素,输入#表示空,按先序顺序输入"<<endl;
	cin>>ch;
	if(ch=="#"){
		//TODO
		node=nullptr;
	}else{
		node=new treenode(stoi(ch));
		create_tree(node->left);
		create_tree(node->right);
	}

}
void inorder(tree&root,arr&a){
	stack<treenode*>sta;
	while(root!=nullptr||!sta.empty()){
		//TODO
		//root!=null是压栈,sta.empty是弹栈时用的判断条件
		while(root!=nullptr){
			//TODO
			sta.push(root);
			root=root->left;
		}
		//此时root指向最左边的子节点(空),开始弹栈
		root=sta.top();
		sta.pop();
		a.push_back(root->data);
		root=root->right;
	}
}
int main(){
	treenode *root=new treenode();
	create_tree(root);
	arr a;
	inorder(root,a);
	for(int num:a){cout<<num<<" ";}
}

括号匹配

///括号匹配
#include<bits/stdc++.h>
using namespace std;
bool is_vaild(string s){
	stack<char>sta;
	for(char ch : s){
		if(ch=='{'||ch=='('||ch=='['){
			//TODO
			sta.push(ch);
		}else{
			if((ch=='}'&&sta.top()=='{')||(ch==']'&&sta.top()=='[')||(ch==')'&&sta.top()=='(')){
				//TODO
				sta.pop();
			}else{
				return false;
			}
		}
	}
	return sta.empty();
}
int main(){
	string s;
	cout<<"请输入括号"<<endl;
	cin>>s;
	bool res=is_vaild(s);
	cout<<res<<endl;
	return 0;
}

最小栈的实现

//双栈实现最小栈,每次压栈或出栈时,最小栈也对应相应的入栈和出栈
#include<bits/stdc++.h>
using namespace std;
class min_stack {
public:
	stack<int>st;
	stack<int>min_st;
	bool pushs(int x){
		if(st.empty()){
			st.push(x);
			min_st.push(x);
			return true;
		}else{
			st.push(x);
			int minpop=min(min_st.top(),x);
			min_st.push(minpop);
			return true;
		}
		return false;
	}
	bool pops(){
		if(st.empty()){
			//TODO
			return false;
		}
		else{
			st.pop();
			min_st.pop();
			return true;
		}
	}
	int top(){
		return st.top();
	}
	int get_min(){
		return min_st.top();
	}
};
int main(){
	min_stack s;
	s.pushs(1);
	s.pushs(-1);
	s.pushs(3);
	s.pops();
	s.pops();
	cout<<s.get_min()<<endl;
	return 0;
}

双栈实现队列

//双栈实现队列
/*一个栈用来入队,一个栈用来出队,
入队时,将元素压入入栈
出队,如果出栈没有元素,就将入栈的元素全部弹出,然后压入出栈,弹出出栈的栈顶元素
如果出栈有元素,那么直接弹出出栈的栈顶元素
队列满:当入栈不能压栈,同时出栈还有元素,就说明队列已满
队列空,两个栈内都没有元素,说明整个队列都没有元素
*/
#include<bits/stdc++.h>
using namespace std;
#define maxsize 100
struct my_stack{
	int data[maxsize];
	int top;
	my_stack():top(-1){}
};
typedef struct my_stack my_stack;
bool is_full(my_stack s){
	if(s.top==maxsize-1){
		//TODO
		return true;
	}
	return false;
}
bool s_is_empty(my_stack s){
	if(s.top<0){
		//TODO
		return true;
	}
	return false;
}
bool push(my_stack&s,int x){
	if(is_full(s)){
		//TODO
		return false;
	}
	s.top++;
	s.data[s.top]=x;
	return true;
}
bool pop(my_stack&s,int&x){
	if(s_is_empty(s)){
		//TODO
		return false;
	}
	x=s.data[s.top];
	s.top--;
	return true;
}
struct dup_stack_que{
	my_stack in;
	my_stack out;
};
typedef struct dup_stack_que dup_stack_que;
bool que_is_empty(dup_stack_que q){
	return s_is_empty(q.in)&&s_is_empty(q.out);
}
bool que_is_full(dup_stack_que q){
	return is_full(q.in)&&(!s_is_empty(q.out));
}
bool push_que(dup_stack_que&q,int x){
	if(que_is_full(q)){
		//TODO
		return false;
	}
	push(q.in,x);
	return true;
}
bool pop_que(dup_stack_que&q,int&x){
	if(que_is_empty(q)){
		//TODO
		return false;
	}
	if(s_is_empty(q.out)){
		//TODO
		int temp;
		while(!s_is_empty(q.in)){
			//TODO
			pop(q.in,temp);
			push(q.out,temp);
		}
		pop(q.out,x);
	}else{
		pop(q.out,x);
	}

	return true;
}
int main(){
	dup_stack_que q;
	int i=1;
	while(i<=5){
		//TODO
		push_que(q,i);
		i++;
	}
	while(!que_is_empty(q)){
		//TODO
		pop_que(q,i);
		cout<<i<<" ";
	}

	return 0;
}

栈实现非递归

//栈实现非递归
/*首先,这里用的是栈的思想,结构体可能不是类似栈的结构
首先结构体储存在那一层n,每一次层计算的结果
最上一层记录的是第0层,然后逐层往下,赋值每一层是入栈过程
计算每一层是出栈过程
*/
#include<bits/stdc++.h>
using namespace std;
#define maxsize 100
struct mystack{
	int n;
	double pnx;
};
typedef struct mystack mystack;
double cac(int n,double x){
	int top=-1,i;
	double f1=1,f2=2*x;
	mystack st[maxsize];
	for(i=n;i>=2;i--){
		//TODO
		top++;
		st[top].n=i;//入栈操作,把第几层标上,由下到上
	}
	//出栈操作开始计算,由上到下
	while(top>=0){
		//TODO
		st[top].pnx=2*x*f2-2*(st[top].n-1)*f1;
		//为下一层做准备
		f1=f2;
		f2=st[top].pnx;
		top--;
	}
	if(n==0) return f1;
	return f2;
}
int main(){
	double x=5;
	int n=3;
	cout<<cac(n,x)<<endl;
}

后缀表达式计算

bool isnumber(string str){
        return !(str=="+"||str=="-"||str=="*"||str=="/");
    }
    int evalRPN(vector<string>& tokens) {
        stack<int> stk;
        int i=0;
        while(i<tokens.size()){
            if(isnumber(tokens[i])){
                stk.push(atoi(tokens[i].c_str()));
            }else{
                int right=stk.top();
                stk.pop();
                int left=stk.top();
                stk.pop();
                int ans=0;
                switch (tokens[i][0]){
                    case '+':{ans=left+right;break;}
                    case '-':{ans=left-right;break;}
                    case '*':{ans=left*right;break;}
                    case '/':{ans=left/right;break;}
                }
                stk.push(ans);
            }
            
            i++;
        }
        return stk.top();
    }

删除无效括号

//一个栈存储左括号,一个栈记录左括号的位置,
    
string minRemoveToMakeValid(string s) {
        stack<char> cs;
        stack<int> pos;
        int i=0;
        while(i<s.size()){
            if(s[i]=='('){
                cs.push(s[i]);
                pos.push(i);
                i++;
            }else if(s[i]==')'){
                if(cs.empty()){
                    s.erase(s.begin()+i);//不满足的符号删除
                    //erase删除后会自动补充,不用i++
                }else{
                    cs.pop();
                    pos.pop();
                    i++;
                }
                
            }else{i++;}
        }
        //如果还有多余的左括号
        while(!pos.empty()){
            s.erase(s.begin()+pos.top());
            pos.pop();
        }
        return s;

    }

队列

循环队列

#include<bits/stdc++.h>
using namespace std;
typedef vector<int> arr;
class circle_queue {

public:
	arr a;
	int front;
	int rear;
	int max_size;
	int temp_size;
	//初始化
	circle_queue(int k):a(k),max_size(k),temp_size(0),front(0),rear(0){}
	bool whether_empty(){
		return temp_size==0;
	}
	bool whether_full(){
		return temp_size==max_size;
	}
	bool push_queue(int data){
		if(whether_full()){return false;}
		a[rear]=data;
		rear=(rear+1)%max_size;
		temp_size++;
		return true;
	}
	bool pop_queue(){
		if(whether_empty()){
			return false;
		}
		front=(front+1)%max_size;
		temp_size--;
		return true;
	}
	int get_front(){
		if(whether_empty()){
			return -1;
		}
		return a[front];
	}
	int get_rear(){
		if(whether_empty()){
			//TODO
			return -1;
		}
		return a[(rear-1+max_size)%max_size];
	}
};
int main(){
	circle_queue q(5);
	q.push_queue(1);
	q.push_queue(2);
	cout<<q.get_front();
	return 0;
}

双端循环队列

//设计循环双端队列,front之后和rear之后是可以确定的,不用加长度取模,其余需要
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vet;
class circle_db_queue {
private:
		int front;
		int rear;
		vet que;
		int max_size;
		int temp_size;
public:
	circle_db_queue(int k):que(k+1),front(0),rear(0),max_size(k+1),temp_size(0){}
	bool whether_full(){
		return (rear+1)%max_size==front;
	}
	bool whether_empty(){return front==rear;}
	bool push_front(int data){
		if(whether_full()){
			return false;
		}
		front--;
		front=(front+max_size)%max_size;
		que[front]=data;
		temp_size++;
		return true;
	}
	bool push_rear(int data){
		if(whether_full()){
			//TODO
			return false;
		}
		que[rear]=data;
		rear++;
		rear=(rear)%max_size;
		temp_size++;
		return true;
	}
	bool pop_front(){
		if(whether_empty()){
			//TODO
			return false;
		}
		front=(front+1)%max_size;
		return true;

	}
	bool pop_rear(){
		if(whether_empty()){
			//TODO
			return false;
		}
		rear--;
		rear=(rear+max_size)%max_size;
		return true;
	}
	int get_front(){
		if(whether_empty()){
			//TODO
			return -1;
		}
		return que[front];
	}
	int get_rear(){
		if(whether_empty()){
			//TODO
			return -1;
		}
		return que[((rear-1)+max_size)%max_size];
	}
};
int main(){
	circle_db_queue duque(5);
	duque.push_front(1);
	duque.push_front(2);
	duque.push_rear(5);
	duque.push_rear(4);
	cout<<duque.get_front();
	cout<<duque.get_rear();
}

双队列实现栈

//用队列实现栈
//两个队列,主队列实现入栈,出栈,弹栈。访问顶端元素,是否为空
//队列和栈的出来顺序相反,所以,每次加入一个数就需要一个辅助队列进行重新排序一下
#include<bits/stdc++.h>
using namespace std;
class stack1 {
public:
	queue<int>zhu1;
	queue<int>fu2;
	//操作主要是根据zhu1队列操作,fu2操作主要是压入新元素来帮助排序
	int pop(){
		int res=zhu1.front();
		zhu1.pop();
		return res;
	}
	bool empty(){return zhu1.empty();}
	int top(){return zhu1.front();}
	void push(int x){
		fu2.push(x);
		//开始从主队列的头指针开始,把元素放新加入的x在后面,最后和主队列交换,始终保证主队列是出栈顺序
		while(!zhu1.empty()){
			//TODO
			fu2.push(zhu1.front());
			zhu1.pop();
		}
		swap(zhu1,fu2);
	}
};
int main(){
	stack1 s;
	s.push(1);
	s.push(2);
	s.push(3);
	while(!s.empty()){
		//TODO
		cout<<s.pop()<<endl;
	}
	return 0;
}

kmp

//KMP算法
#include<bits/stdc++.h>
using namespace std;
vector<int> get_next(string t){
	int i=1,j=0;
	vector<int> next(100);
	next[1]=0;
	while(i<t.size()){
		//TODO
		if(j==0||t[i]==t[j]){
			//TODO
			i++;
			j++;
			next[i]=j;
		}else{
			j=next[j];
		}
	}
	return next;
}
int kmp(string s,string t,vector<int> next){
	int i=1,j=1;
	while(i<s.size()&&j<t.size()){
		//TODO
		if(j==0||s[i]==t[j]){
			//TODO
			i++;
			j++;
		}else{
			j=next[j];
		}
	}
	if(j>=t.size()){
		//TODO
		return i-t.size()+1;
	}else{
		return 0;
	}
}
int main(){
	string s="#";
	string s1;
	cout<<"输入总串"<<endl;
	cin>>s1;
	s=s+s1;
	cout<<s<<endl;
	string t="#";
	string t1;
	cout<<"输入模式串"<<endl;
	cin>>t1;
	t=t+t1;
	cout<<t<<endl;
	vector<int> next=get_next(t);

	cout<<endl;
	cout<<kmp(s,t,next);
}

暴力匹配

//暴力匹配
#include<bits/stdc++.h>
using namespace std;
int match(string s,string t){
	int i=1,j=1,k=1;
	while(i<s.size()&&j<t.size()){
		//TODO
		if(s[i]==t[j]){
			//TODO
			i++;
			j++;
		}else{
			k++;
			i=k;
			j=1;
		}
	}
	if(j>=t.size()){
		//TODO
		return k;
	}else{
		return 0;
	}
}
int main(){
	cout<<"输入总串"<<endl;
	string s="#";
	string s1;
	cin>>s1;
	s=s+s1;
	cout<<s<<endl;
	cout<<"输入模式串"<<endl;
	string t="#";
	string t1;
	cin>>t1;
	t=t+t1;
	cout<<t<<endl;
	cout<<match(s,t)<<endl;
}

二叉树

二叉树中序遍历

//二叉树的中序遍历,递归方法
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode*left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
	treenode(int x,struct treenode*left,struct treenode*right):data(x),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void creat(tree&root){
	cout<<"请按先序遍历输入,#表示空"<<endl;
	string ch;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;
		return;
	}
	root=new treenode(stoi(ch));
	creat(root->left);
	creat(root->right);
}
void inorder(tree&root){
	if(root==nullptr) return;
	else{
		inorder(root->left);
		cout<<root->data<<" ";
		inorder(root->right);
	}

}
int main(){
	tree root;
	creat(root);
	inorder(root);
	return 0;
}

二叉树层次遍历

//二叉树的层次遍历
#include<bits/stdc++.h>
using namespace std;
#define maxsize 100
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
struct myque{
	treenode* data[maxsize];
	int f,r,tag;
	myque():f(0),r(0),tag(0){}
};
typedef struct myque myque;
bool qu_isempty(myque que){
	if(que.f==que.r&&que.tag==0){
		//TODO
		return true;
	}
	return false;
}
bool qu_isfull(myque que){
	if(que.f==que.r&&que.tag==1){
		//TODO
		return true;
	}
	return false;
}
bool enque(treenode *&root,myque&q){
	if(qu_isfull(q)){
		//TODO
		return false;
	}
	q.data[q.r]=root;
	q.r=(q.r+1)%maxsize;
	q.tag=1;
	return true;
}
bool outque(treenode *&root,myque&q){
	if(qu_isempty(q)){
		//TODO
		return false;
	}
	root=q.data[q.f];
	q.f=(q.f+1)%maxsize;
	q.tag=0;
	return true;
}
void create(tree&root){
	cout<<"输入先序序列,#表示为空"<<endl;
	string ch;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;
		return;
	}else{
		int data=stoi(ch);
		root=new treenode(data);
		create(root->left);
		create(root->right);
	}
}
void level(tree&root){
	myque q;
	enque(root,q);
	while(!qu_isempty(q)){
		//TODO
		outque(root,q);
		cout<<root->data<<" ";
		if(root->left!=nullptr){
			//TODO
			enque(root->left,q);
		}
		if(root->right!=nullptr){
			//TODO
			enque(root->right,q);
		}
	}

}
int main(){
	tree root;
	create(root);
	level(root);
}

非递归求二叉树深度

//非递归二叉树的深度或者高度,逐层压入,每压完一层,深度加1
#include<bits/stdc++.h>
#define maxsize 100
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
struct myque{
	treenode* data[maxsize];
	int f,r,tag;
	myque():f(0),r(0),tag(0){}
};
typedef struct myque myque;
int volume(myque q){
	return (maxsize-(q.f-q.r))%maxsize;
}
bool q_isempty(myque q){
	return q.f==q.r&&q.tag==0;
}
bool q_isfull(myque q){
	return q.f==q.r&&q.tag==1;
}
bool push(myque&q,tree&root){
	if(q_isfull(q)){
		//TODO
		return false;
	}
	q.data[q.r]=root;
	q.r=(q.r+1)%maxsize;
	q.tag=1;
	return true;
}
bool pop(myque&q,tree&root){
	if(q_isempty(q)){
		//TODO
		return false;
	}
	root=q.data[q.f];
	q.f=(q.f+1)%maxsize;
	q.tag=0;
	return true;
}
void create(tree&root){
	cout<<"先序序列输入,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
int depth(tree&root){
	myque q;
	if(root==nullptr){
		//TODO
		return -1;
	}
	push(q,root);
	int level=0;
	while(!q_isempty(q)){
		int temp=volume(q);
		//把当前层的结点依次弹出,然后压入它的孩子结点
		//TODO
		for(int i=0;i<temp;i++){
			//TODO
			pop(q,root);
			if(root->left!=nullptr){
				//TODO
				push(q,root->left);
			}
			if(root->right!=nullptr){
				//TODO
				push(q,root->right);
			}
		}
		level++;
	}
	return level;
}
int main(){
	tree root;
	create(root);
	cout<<depth(root)<<endl;
	return 0;
}

求二叉树宽度

//寻找二叉树的宽度,层次遍历
#include<bits/stdc++.h>
#define maxsize 100
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
struct myque{
	treenode* data[maxsize];
	int f,r,tag;
	myque():f(0),r(0),tag(0){}
};
typedef struct myque myque;
int qsize(myque q){return (maxsize-(q.f-q.r))%maxsize;}
bool q_isfull(myque q){return q.f==q.r&&q.tag==1;}
bool q_isempty(myque q){return q.f==q.r&&q.tag==0;}
bool push(myque&q,tree&root){
	if(q_isfull(q)){
		//TODO
		return false;
	}
	q.data[q.r]=root;
	q.r=(q.r+1)%maxsize;
	q.tag=1;
	return true;
}
bool pop(myque&q,tree&root){
	if(q_isempty(q)){
		//TODO
		return false;
	}
	root=q.data[q.f];
	q.f=(q.f+1)%maxsize;
	q.tag=0;
	return true;
}
void create(tree&root){
	//treenode *t=root;
	cout<<"先序输入,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
int width(tree &root){
	if(root==nullptr){
		//TODO
		return 0;
	}
	treenode *t=root;
	myque q;
	push(q,t);
	int wid=0;
	while(!q_isempty(q)){
		int tempsize=qsize(q);
		//TODO
		wid=max(wid,tempsize);

		for(int i=1;i<=tempsize;i++){
			//TODO
			pop(q,t);
			if(t->left!=nullptr){
				//TODO
				push(q,t->left);
			}
			if(t->right!=nullptr){
				//TODO
				push(q,t->right);
			}
		}
	}
	return wid;
}
int main(){
	tree root;
	create(root);
	cout<<width(root)<<endl;
	return 0;
}

二叉排序树的判断

//判断一棵树是不是二叉排序树
//中序遍历二叉树,看是不是升序
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int data):data(data),left(nullptr),right(nullptr){}
	treenode(int data,struct treenode*left,struct treenode*right):data(data),left(left),right(right){}
};
typedef vector<int> arr;
typedef struct treenode treenode;
typedef struct treenode* tree;
void creat_tree(tree&root){
	cout<<"请按先序输入,#表示空"<<endl;
	string ch;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;
		return;
	}else{
		int data=stoi(ch);
		root=new treenode(data);
		creat_tree(root->left);
		creat_tree(root->right);
	}
}
void inorder(tree&root,arr&a){
	stack<treenode*>stree;
	while(root!=nullptr||!stree.empty()){
		//TODO
		while(root!=nullptr){
			//TODO
			stree.push(root);
			root=root->left;
		}
		root=stree.top();
		stree.pop();
		a.push_back(root->data);
		root=root->right;
	}


}
int main(){
	arr a;
	treenode *root;
	creat_tree(root);
	inorder(root,a);
	cout<<is_sorted(a.begin(),a.end());
	return 0;
}
//方法二
bool isValidBST(TreeNode* root) {
        //非递归中序遍历确保有序
        long long int predata=(long long)INT_MIN-1;
        stack<TreeNode*> mystack;
        while(root!=nullptr||!mystack.empty()){
            while(root!=nullptr){
                mystack.push(root);
                root=root->left;
            }
            root=mystack.top();
            mystack.pop();
            if(root->val<=predata){return false;}//和前者作比较
            predata=root->val;//储存值
            root=root->right;

        }
        return true;
    }

合并二叉树

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == nullptr) {
            return t2;
        }
        if (t2 == nullptr) {
            return t1;
        }
        auto merged = new TreeNode(t1->val + t2->val);
        merged->left = mergeTrees(t1->left, t2->left);
        merged->right = mergeTrees(t1->right, t2->right);
        return merged;
    }
};

二叉树第二小结点

class Solution {
public:
    int findSecondMinimumValue(TreeNode* root) {
        if(!root || !root->left || !root->right) return -1;//空节点或不满足题意
        
        int left=root->left->val,right=root->right->val;
        
        //若根节点和左节点值相同,则递归找左子树的第二小节点
        if(root->val==root->left->val) left=findSecondMinimumValue(root->left);
        //若根节点和右节点值相同,则递归找右子树的第二小节点
        if(root->val==root->right->val) right=findSecondMinimumValue(root->right);

        //若根节点等于左右子树的第二小节点返回-1
        if(root->val==left && root->val==right) return -1;

        //根据当前的根、左右节点的值继续判断
        int min_lr=min(left,right);
        if(root->val<min_lr) return min_lr;//根节点小于最小值,返回最小值
        else return max(left,right);//根节点与子树的值相等,第二小只能是比最小的还要大
    }

};

判断结点是不是堂兄弟

bool iscousn(tree&root,int x,int y){
	if(root==nullptr){
		//TODO
		return false;
	}
	myque q;
	pushq(q,root);
	bool flag1=false;
	while(!qisempty(q)){
		//TODO
		int volume=qsize(q);
		int i=0;
		while(i<volume){
			//TODO
			popq(q,root);
			if(root->left!=nullptr){
				//TODO
				pushq(q,root->left);
			}
			if(root->right!=nullptr){
				//TODO
				pushq(q,root->right);
			}
			if(root!=nullptr&&root->data==x){
				//TODO
				flag1=true;
				
			}
			if(flag1==true&&root->data==y){
				//TODO
				return true;
			}
			i++;
		}
	}
	return false;
}

非递归后序遍历求叶子结点路径

void findpath(tree&root){
	myt sta[100];
	int top=0;
	while(root!=nullptr||top>0){
		//TODO
		while(root!=nullptr){
			//TODO
			top++;
			sta[top].root=root;
			sta[top].tag=0;//表示左节点已经访问过
			
			root=root->left;
		}
		//此时跳出循环应该是遇到叶子结点的空结点,栈顶肯定是叶子结点
		cout<<sta[top].root->data<<"的路径是"<<endl;
		int i=1;
		while(i<=top){
			//TODO
			cout<<sta[i].root->data<<" ";
			i++;
		}
		//弹出已经访问过右节点的结点
		while(top>0&&sta[top].tag==1){
			//TODO
			top--;
		}
		if(top>0){
			//TODO
			sta[top].tag=1;
			root=sta[top].root->right;
		}
	}
	
	
}

二叉排序树调整

void inorder(tree &root){
        if(root) {
            inorder(root->left);
            temp.push_back(root->val);
            inorder(root->right);
        }
        
    }
//中序遍历储存数值
    void inorder_change(tree &root,vector<int> &temp){
        if(root){
            inorder_change(root->left,temp);
            root->val=temp[cnt];
            cnt++;
            cout<<root->val<<endl;
            inorder_change(root->right,temp);    
        
        } 
        
        
    }
//中序重新创建二叉树
    void recoverTree(TreeNode* root) {
        inorder(root);
     
        sort(temp.begin(),temp.end());//排序然后重新遍历root,进行修改
        for(int num:temp){cout<<num;}
        cout<<endl;
        inorder_change(root,temp);
        
    }

寻找二叉树相同子树序列

//二叉树的序列化,判断是否有相同子树,从最底层开始往上找,所以需要深度优先遍历
//深度优先遍历这里采用先序遍历,然后从底到高记录下序列,每次加入序列就检查是否有重复序列出现
typedef struct TreeNode* tree;

    vector<TreeNode*> res;
    unordered_map<string,int>map;
    //int res=0;
    string dfs(tree&root,unordered_map<string,int>&map,vector<TreeNode*>&res){
        if(root==nullptr) return "";
        string str=to_string(root->val)+","+dfs(root->left,map,res)+","+dfs(root->right,map,res);
        if(map[str]==1){
            res.push_back(root);
        }
        map[str]++;
        return str;
    }
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
        dfs(root,map,res);
        return res;
    }

二叉树最长同值路径

public:
	//递归看,同值路径必须要经过每一个根
    int res=0;

    int dfs(tree&root){
        if(root==nullptr) return 0;
        int left=0,right=0;
        int leftend=0,rightend=0;
        left=dfs(root->left);
        right=dfs(root->right);
        if(root->left!=nullptr&&root->val==root->left->val){
            leftend=left+1;
        }
        if(root->right!=nullptr&&root->right->val==root->val){
            rightend=right+1;
        }

        res=max(res,leftend+rightend);
        return max(leftend,rightend);
    }
    int longestUnivaluePath(TreeNode* root) {
        //最长同值路径也是采用递归思想
        //去看左子树的最大同值路径,右子树的最大同直路径,
        //然后看与根值是否相同,左边相同左边+1,否则就归0
        dfs(root);
        return res;

    }

左右子树交换是否满足先序序列

vector<int> res;
    int i=0;
    bool dfs(tree&root,vector<int>&voyage){
        if(root==nullptr) return true;
        if(root->val!=voyage[i]) return false;
        i++;
        if(dfs(root->left,voyage)&&dfs(root->right,voyage)){
            return true;
        }
        if(dfs(root->right,voyage)&&dfs(root->left,voyage)){
            res.push_back(root->val);
            return true;
        }
        return false;
    }
    vector<int> flipMatchVoyage(TreeNode* root, vector<int>& voyage) {
        if(dfs(root,voyage)){
            return res;
        }
        res.erase(res.begin(),res.end());
        res.push_back(-1);
        return res;
    }

后序遍历删除特定叶子结点

TreeNode* removeLeafNodes(TreeNode* root, int target) {
        if(root==nullptr) return nullptr;
        root->left=removeLeafNodes(root->left,target);
        root->right=removeLeafNodes(root->right,target);
        if(root->left==nullptr&&root->right==nullptr&&root->val==target){
            return nullptr;
        }
        return root;

    }

二叉搜索树删除结点并调整

TreeNode* deleteNode(TreeNode* root, int key) {
        if(root==nullptr) return nullptr;
        if(key>root->val){
            root->right=deleteNode(root->right,key);
        }
        else if(key<root->val){
            root->left=deleteNode(root->left,key);
        }
        else{
            if(root->left==nullptr&&root->right==nullptr) return nullptr;
            if(root->left==nullptr&&root->right!=nullptr) return root->right;
            if(root->right==nullptr&&root->left!=nullptr) return root->left;
            if(root->left!=nullptr&&root->right!=nullptr){
                TreeNode *node=root->right;
                while(node->left!=nullptr){
                    node=node->left;
                }
                node->left=root->left;
                root=root->right;
                
            }

        }
        return root;
    }

寻找结点最大乘积

//实现两个数的最大乘积,和一定,那么最大乘积一定是两数平分,所以,
//只有当分出的数越接近、sum的一半乘积越大
typedef struct TreeNode treenode;
typedef struct TreeNode* tree;
class Solution {
public:
    int sum=0;
    int partnum=0;
    int partsum=0;
    void dfs(tree&root){
        if(root!=nullptr){
            sum+=root->val;
            dfs(root->left);
            dfs(root->right);
        }
    }
    int findpart(tree&root){
        if(root==nullptr) return 0;
        else{
            partsum=root->val+findpart(root->left)+findpart(root->right);
        
            if(abs(2*partsum-sum)<abs(2*partnum-sum)){
            partnum=partsum;
            }
        
            return partsum;

        }
    }
    int maxProduct(TreeNode* root) {
        dfs(root);
        findpart(root);
        cout<<sum;
        return ((unsigned long)partnum * (sum-partnum)) % 1000000007;

    }
};

判断二叉树是否对称

//判断一棵树是不是对称树
//看左子树的左子树与右子树的右子树是否相等
//看左子树的右子树与右子树的左子树是否相等
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int data):data(data),left(nullptr),right(nullptr){}
	treenode(int data,struct treenode*left,struct treenode*right):data(data),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void creat_tree(tree&root){
	cout<<"请输入每个结点,#表示空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}else{
		int data=stoi(str);
		root=new treenode(data);
		creat_tree(root->left);
		creat_tree(root->right);
	}
}
bool is_symmetry(treenode *p,treenode *q){
	if(q==nullptr&&p==nullptr) return true;//两节点都为空
	else if(q==nullptr||p==nullptr){
		//TODO
		return false;
	}else{
		return p->data==q->data&&is_symmetry(p->left,q->right)&&is_symmetry(p->right,q->left);
	}
}
int main(){
	treenode *root;
	creat_tree(root);
	bool res= is_symmetry(root,root);
	cout<<res<<endl;
	return 0;
}

二叉树结构是否相同

//判断两棵树是否相同
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode*left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int data):data(data),left(nullptr),right(nullptr){}
	treenode(int data,struct treenode*left,struct treenode*right):data(data),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void creat_tree(tree&root){
	cout<<"请按先序遍历输入,输入#表示结点为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		root=nullptr;
		return;
	}
	root=new treenode(stoi(str));
	creat_tree(root->left);
	creat_tree(root->right);

}
bool is_same_tree(tree&tr1,tree&tr2){
	if(tr1==nullptr&&tr2==nullptr){
		//TODO
		return true;
	}else if(tr1==nullptr||tr2==nullptr){
		//TODO
		return false;
	}else if(tr1->data!=tr2->data){
		//TODO
		return false;
	}else{
		//两个结点相等后,继续深度遍历判断
		return is_same_tree(tr1->left,tr2->left)&&is_same_tree(tr1->right,tr2->right);
	}
}
int main(){
	tree tr1;
	tree tr2;
	creat_tree(tr1);
	cout<<"请输入第二棵树"<<endl;
	creat_tree(tr2);
	cout<<is_same_tree(tr1,tr2);
	return 0;
}

平衡二叉树的判断

//判断平衡二叉树
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
	treenode(int x,struct treenode *left,struct treenode *right):data(x),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create_tree(tree&root){
	//先序方式创建
	cout<<"请输入结点值,#表示空"<<endl;
	string ch;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;
		return;
	}else{
		int data=stoi(ch);
		root=new treenode(data);
		create_tree(root->left);
		create_tree(root->right);
	}

}
int depth(tree&root){
	if(root==nullptr){
		//TODO
		return 0;
	}else{
		return max(depth(root->left),depth(root->right))+1;
	}
}
bool is_balanced(tree&root){
	if(root==nullptr){
		//TODO,空树也是平衡树
		return true;
	}else{
		//递归判断
		return abs(depth(root->left)-depth(root->right))<=1 && is_balanced(root->left) && is_balanced(root->right);
	}
}
int main(){
	tree root;
	create_tree(root);
	cout<<is_balanced(root)<<endl;
	return 0;
}

求二叉树最小深度

//求二叉树的最小深度
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
	treenode(int x,struct treenode *left,struct treenode *right):data(x),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create_tree(tree&root){
	cout<<"请按先序顺序输入,#表示为空"<<endl;
	string ch;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;
		return;
	}else{
		int data=stoi(ch);
		root=new treenode(data);
		create_tree(root->left);
		create_tree(root->right);
	}
}
int min_depth(tree&root){
	int min_depth_recur=INT_MAX;
	if(root==nullptr){
		//TODO
		return 0;
	}
	if(root->left==nullptr&&root->right==nullptr){
		return 1;//此时root是叶子结点
		//TODO
	}//不是叶子结点开始递归

	else{

		if(root->left!=nullptr){
			//TODO
			min_depth_recur=min(min_depth(root->left),min_depth_recur);
		}
		//这么写if是避免了漏掉左子树为空,右子树不为空的
		if(root->right!=nullptr){
			//TODO
			min_depth_recur=min(min_depth(root->right),min_depth_recur);
		}

	}
	return min_depth_recur+1;
}
int main(){
	tree root;
	create_tree(root);
	cout<<min_depth(root)<<endl;
	return 0;
}

特定路径总和

//路径总和
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
	treenode(int x,struct treenode*left,struct treenode*right):data(x),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create_tree(tree&root){
	cout<<"请按先序输入,#表示为空"<<endl;
	string ch;
	cin>>ch;
	if(ch=="#"){
		//TODO
		root=nullptr;
		return;
	}else{
		int data=stoi(ch);
		root=new treenode(data);
		create_tree(root->left);
		create_tree(root->right);
	}
}
bool sum_path(tree&root,int sum){
	if(root==nullptr){
		//TODO
		return false;
	}
	if(root->left==nullptr&&root->right==nullptr&&root->data==sum){
		//TODO
		return true;
	}
	return sum_path(root->left,sum-root->data)||sum_path(root->right,sum-root->data);
}
int main(){
	tree root;
	create_tree(root);
	cout<<sum_path(root,4)<<endl;
	return 0;
}

有序数组转换为二叉树

//有序数组转化位二叉搜索树
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left,*right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
	treenode(int x,struct treenode*left,struct treenode*right):data(x),left(left),right(right){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
typedef vector<int> arr;
treenode* create_search(arr&num,int left,int right){
	if(left<0||right>num.size()||left>right){
		//TODO
		return nullptr;
	}
	//递归出口
	if(left==right){
		//TODO
		return new treenode(num[left]);
	}
	int mid=(left+right)/2;
	treenode *root=new treenode(num[mid]);//创建结点
	//继续递归
	root->left=create_search(num,left,mid-1);
	root->right=create_search(num,mid+1,right);
	return root;
}
//先序遍历
void print(tree&root)
{
	if(root==nullptr){
		//TODO
		return ;
	}
	cout<<root->data<<" ";
	print(root->left);
	print(root->right);
}

int main(){
	arr a{1,2,3,4,5,6,7,8,9};
	int left=0,right=a.size()-1;
	treenode *test=create_search(a,left,right);
	print(test);
	return 0;

}

二叉排序树解决TOP-K问题

//二叉搜索树找到第k小个元素
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	int count;//这里的count包含根节点,所以初始化时赋值1
	treenode():data(-1),left(nullptr),right(nullptr),count(1){}
	treenode(int x):data(x),left(nullptr),right(nullptr),count(1){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
typedef vector<int> myarray;
myarray test{78,56,100,34,120,399,32};
void insert_node(tree&root,int data){
	if(root==nullptr){
		//TODO
		root=new treenode(data);
		return;
	}
	if(root->data==data){
		//TODO
		cout<<"数值已存在无法插入"<<endl;
		return;
	}
	else if(root->data<data){
		//TODO
		root->count++;
		insert_node(root->right,data);
	}
	else{
		root->count++;
		insert_node(root->left,data);
	}
}
void create(tree&root,myarray test){
	int i=0;
	while(i<test.size()){
		//TODO
		insert_node(root,test[i]);
		i++;
	}
}
int findnum(tree&root,int k){
	if(k<1||k>root->count) return -1;
	if(root->left==nullptr){
		//TODO
		//左子树为空,第k小去右子树找,
		if(k==1){
			//TODO,根节点
			return root->data;
		}
		return findnum(root->right,k-1);//从上往下找,直到k减为1,就是第k小
	}
	else{
		if(root->left->count==k-1){
			//TODO
			return root->data;
		}
		if(root->left->count>k-1){
			//TODO
			return findnum(root->left,k);//这里不用减一
		}
		if(root->left->count<k-1){
			//先执行上面的if,然后count不断减小,再来执行这个if
			return findnum(root->right,k-(root->left->count+1));
		}
	}
}
int main(){
	tree root;
	create(root,test);
	cout<<findnum(root,2);
	return 0;
}

层次遍历判断完全二叉树

//层序遍历解决完全二叉树的判定
#include<bits/stdc++.h>
#define maxsize 100
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
struct myque{
	treenode* data[maxsize];
	int f,r,tag;
	myque():f(0),r(0),tag(0){}
};
typedef struct myque myque;
int qsize(myque q){return (maxsize-(q.f-q.r))%maxsize;}
bool qisfull(myque q){return q.f==q.r&&q.tag==1;}
bool qisempty(myque q){return q.f==q.r&&q.tag==0;}
bool pushq(myque&q,treenode* root){
	if(qisfull(q)){
		//TODO
		return false;
	}
	q.data[q.r]=root;
	q.r=(q.r+1)%maxsize;
	return true;
}
bool popq(myque&q,tree&root){
	if(qisempty(q)){
		//TODO
		return false;
	}
	root=q.data[q.f];
	q.f=(q.f+1)%maxsize;
}
void create(tree&root){
	cout<<"先序树,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
void display(tree&root){
	if(root==nullptr){
		//TODO
		return;
	}
	cout<<root->data<<" ";
	display(root->left);
	display(root->right);
}
bool level_bianli(tree&root){
	if(root==nullptr){
		//TODO
		return true;
	}
	myque q;
	pushq(q,root);
	while(!qisempty(q)){
		//TODO
		//当遇到空结点时,不断出队,只要由非空结点,就说明不是完全二叉树
		popq(q,root);
		if(root!=nullptr){
			//TODO
			pushq(q,root->left);
			pushq(q,root->right);
		}else{
			//遇到空结点,后面应该都是空结点
			while(!qisempty(q)){
				//TODO
				popq(q,root);
				if(root!=nullptr){
					//TODO
					return false;
				}
			}
		}

	}
	return true;
}
int main(){
	tree root;
	create(root);
	display(root);
	cout<<endl;
	cout<<level_bianli(root);
	return 0;
}

线索二叉树

//创建线索二叉树
#include<bits/stdc++.h>
using namespace std;
struct threadnode{
	int data;
	struct threadnode *left;
	struct threadnode *right;
	int ltag;
	int rtag;
	threadnode():data(-1),left(nullptr),right(nullptr),ltag(0),rtag(0){}
	threadnode(int x):data(x),left(nullptr),right(nullptr),ltag(0),rtag(0){}
};
typedef struct threadnode threadnode;
typedef struct threadnode* threadtree;
//先创建出树才能线索化
threadnode *pre=nullptr;
void createtree(threadtree&root){
	cout<<"先序遍历顺序输入,#表示空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
	}else{
		int data=stoi(str);
		root=new threadnode(data);
		createtree(root->left);
		createtree(root->right);
	}

}
void visit(threadtree&root){
	//当前结点的左子树为空,要么前驱结点的右子树为空,只有这两种情况
	//中序遍历线索化,只有最后没有孩子了,前驱和后继才能赋值
	//助记,中序线索化,就是为了找前驱,当前结点左子树为空,才能赋值前驱
	if(root->left==nullptr){
		//TODO
		root->left=pre;
		root->ltag=1;
	}
	if(pre!=nullptr&&pre->right==nullptr){
		//TODO
		pre->right=root;
		pre->rtag=1;
	}
	pre=root;
}
void vesttree(threadtree&root){
	if(root==nullptr){
		//TODO
		return;
	}else{
		vesttree(root->left);
		visit(root);
		vesttree(root->right);
	}

}
void create_threadtree(threadtree&root){
	if(root==nullptr){
		//TODO
		return;
	}
	else{
		vesttree(root);
		if(pre->right==nullptr){
			//TODO
			pre->rtag=1;
		}
	}

}
void bianli(threadtree&root){
	if(root==nullptr){
		//TODO
		return;
	}else{

		cout<<root->data<<" "<<root->ltag<<" "<<root->rtag<<endl;
		if(root->ltag==0){
			bianli(root->left);
		}
		if(root->rtag==0){
			//TODO
			bianli(root->right);
		}

	}
}
//寻找子树的第一个结点
threadnode* firstnode(threadtree&root){
	while(root->ltag==0){
		//TODO
		root=root->left;
	}
	return root;
}
//寻找某个结点的后继,就是寻找这个结点右子树的第一个结点
threadnode* nextnode(threadtree&root){
	if(root->rtag==0){
		//TODO
		return firstnode(root->right);
	}
	return root->right;
}
void real_bianli(threadtree&root){
	for(threadnode *p=firstnode(root);p!=nullptr;p=nextnode(p)){
		//TODO
		cout<<p->data<<" ";
	}
}
//找子树的最后一个结点,就是找子树的最右边的结点
threadnode* lastnode(threadtree&root){
	while(root->rtag==0){
		//TODO
		root=root->right;
	}
	return root;
}
//找前驱就是找左子树的最后一个结点
threadnode* prenode(threadtree&root){
	if(root->ltag==0){
		//TODO
		return lastnode(root->left);
	}
	return root->left;
}
void real_bianli2(threadtree&root){
	for(threadnode *p=lastnode(root);p!=nullptr;p=prenode(p)){
		//TODO
		cout<<p->data<<" ";
	}
}
int main(){
	threadtree root;
	createtree(root);
	create_threadtree(root);
	bianli(root);//直接遍历会成环
	real_bianli(root);
	cout<<endl;
	cout<<root->data<<endl;
	real_bianli2(root);
	return 0;
}

从左到右结点串成串

//中序遍历将叶子结点串成串
#include<bits/stdc++.h>
using namespace std;
#define maxsize 100
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
struct mystack{
	treenode* data[maxsize];
	int top;
	mystack():top(-1){}
};
struct listnode{
	int data;
	struct treenode *next;
	listnode():data(-1),next(nullptr){}
};
typedef struct listnode listnode;
typedef struct mystack mystack;
bool s_isempty(mystack s){return s.top==-1;}
bool s_isfull(mystack s){return s.top==maxsize-1;}
bool spush(mystack&s,tree&root){
	if(s_isfull(s)){
		//TODO
		return false;
	}
	s.top++;
	s.data[s.top]=root;
	return true;
}
bool spop(mystack&s,tree&root){
	if(s_isempty(s)){
		//TODO
		return false;
	}
	root=s.data[s.top];
	s.top--;
	return true;
}
void create(tree&root){
	cout<<"输入先序序列,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);

}
mystack s;
listnode *p_head=new listnode();
void lis(tree&root){
	treenode *temp;
	if(root==nullptr){
		//TODO
		return;
	}
	//不断向左遍历,直到找到最左边的叶子结点
	lis(root->left);
	if(root->left==nullptr&&root->right==nullptr){
		//TODO
		if(s_isempty(s)){
			//TODO
			p_head->next=root;
			spush(s,root);
		}else{
			spop(s,temp);
			temp->right=root;
			spush(s,root);
		}
	}
	lis(root->right);

}
int main(){
	tree root;
	create(root);
	lis(root);
	root=p_head->next;
	while(root!=nullptr){
		//TODO
		cout<<root->data<<" ";
		root=root->right;

	}
	return 0;
}

判断两树相似

//递归判断两树相似
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create(tree&root){
	cout<<"先序输入,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
bool is_similar(tree&root1,tree&root2){
	if(root1==nullptr&&root2==nullptr){
		//TODO
		return true;
	}
	else if(root1==nullptr||root2==nullptr){
		//TODO
		return false;
	}else{
		return is_similar(root1->left,root2->left)&&is_similar(root1->right,root2->right);
	}
}
int main(){
	tree root1;
	tree root2;
	cout<<"第一棵树"<<endl;
	create(root1);
	cout<<"第二棵树"<<endl;
	create(root2);
	if(is_similar(root1,root2)){
		//TODO
		cout<<"相似"<<endl;
	}else{cout<<"不相似"<<endl;}
	return 0;
}

二叉树最近公共祖先

//寻找二叉树的最近公共祖先
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create(tree&root){
	cout<<"按先序序列输入,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
treenode* ancestor(tree&root,int p,int q){
	//不断递归,无论那一层,当p,q,出现在根节点上
	if(root==nullptr||root->data==p||root->data==q){
		return root;//从上往下递归,每一层都先看,每一层的root,是不是这两个数,才往下递归
	}
	//说明根不是这两个,开始分别去左子树和右子树看
	treenode* lef=ancestor(root->left,p,q);
	treenode* righ=ancestor(root->right,p,q);
	if(lef==nullptr){
		//TODO说明,没有找到这两个中的任一个
		return righ;
	}
	if(righ==nullptr){
		//TODO
		return lef;
	}
	//都找到说明,在两个分支上
	return root;//就将这一层的root返回
}
int main(){
	tree root;
	create(root);
	int p,q;
	cout<<"输入p,q"<<endl;
	cin>>p>>q;
	root=ancestor(root,p,q);
	cout<<root->data<<endl;
	return 0;
}

孩子兄弟表示法计算叶子结点个数

#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create(tree&root){
	cout<<"先序输入,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
int leaves(tree&root){

	if(root==nullptr){
		//TODO
		return 0;
	}
	if(root->left==nullptr){
		//TODO
		return 1+leaves(root->right);
	}
	else{
		return leaves(root->left)+leaves(root->right);
	}
}
int main(){
	tree root;
	create(root);
	cout<<leaves(root)<<endl;
	return 0;
}

孩子兄弟表示法求树深度

#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create(tree&root){
	cout<<"先序输入,#表示空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
int height(tree&root){
	if(root==nullptr){
		//TODO
		return 0;
	}
	else{
		int hleft=height(root->left);
		int hright=height(root->right);
		return max(hleft+1,hright);
	}

}
int main(){
	tree root;
	create(root);
	cout<<height(root)<<endl;
	return 0;
}

根据满二叉树的先序求后序

//满二叉树的后序序列
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> arr;

void post(arr data,int s,int en,arr&a,int s1,int en1){
	int mid;//左右子树分割
	if(s<=en){
		//TODO
		//满二叉树是对称图形,前序序列与后序序列不同的是,根位置发生了变化,其余不变
		a[en1]=data[s];//后序遍历的后面是前序遍历的前面
		mid=(en-s)/2;
		post(data,s+1,s+mid,a,s1,s1+mid-1);
		post(data,s+mid+1,en,a,s1+mid,en1-1);
	}


}
int main(){
	arr data={1,2,4,5,3,6,7};
	arr a(7);
	post(data,0,data.size(),a,0,6);
	for(int num:a){cout<<num<<" ";}
}

根据先序和后序构建二叉树

//先序和中序,二叉树的重构
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),left(nullptr),right(nullptr){}
	treenode(int x):data(x),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
int pos=0;//全局变量,
void create(tree&root,int pre[],int inorder[],int s,int end){
	if(s<=end){
		//TODO
		root=new treenode(pre[pos]);

		//找到根节点在中序的下标,然后就可以分开递归
		int i;
		for(i=s;i<=end;i++){
			//TODO
			if(inorder[i]==pre[pos]){
				//TODO
				break;
			}
		}
		pos++;//准备下一个根节点
		create(root->left,pre,inorder,s,i-1);//准备左子树
		create(root->right,pre,inorder,i+1,end);//准备右子树
	}
}
void preorder(tree&root){
	if(root==nullptr){
		//TODO
		return;
	}else{
		cout<<root->data<<" ";
		preorder(root->left);
		preorder(root->right);
	}

}
void sinorder(tree&root){
	if(root==nullptr){
		//TODO
		return;
	}else{

		sinorder(root->left);
		cout<<root->data<<" ";
		sinorder(root->right);
	}
}
int main(){
	int pre[]={1,2,4,5,3};
	int inorder[]={4,2,5,1,3};
	tree root;
	create(root,pre,inorder,0,4);
	preorder(root);
	//sinorder(root);
}

中序线索化后找后序前驱

//中序线索化,找后序前驱
#include<bits/stdc++.h>
using namespace std;
struct treenode{
	int data;
	int ltag;
	int rtag;
	struct treenode *left;
	struct treenode *right;
	treenode():data(-1),ltag(0),rtag(0),left(nullptr),right(nullptr){}
	treenode(int x):data(x),ltag(0),rtag(0),left(nullptr),right(nullptr){}
};
typedef struct treenode treenode;
typedef struct treenode* tree;
void create(tree&root){
	cout<<"先序输入,#为空"<<endl;
	string str;
	cin>>str;
	if(str=="#"){
		//TODO
		root=nullptr;
		return;
	}
	int data=stoi(str);
	root=new treenode(data);
	create(root->left);
	create(root->right);
}
//中序线索化
treenode *pre=nullptr;
void vithread(tree&root){
	if(root==nullptr){
		//TODO
		return;
	}
	if(root->left==nullptr){
		//TODO
		root->left=pre;
		root->ltag=1;
	}
	if(pre!=nullptr&&pre->right==nullptr){
		//TODO
		pre->right=root;
		pre->rtag=1;
	}
	pre=root;
}
void inorderth(tree&root){
	if(root==nullptr){
		//TODO
		return;
	}
	inorderth(root->left);
	vithread(root);
	inorderth(root->right);
}
void start_inorder(tree&root){
	if(root==nullptr){
		//TODO
		return;
	}
	inorderth(root);
	if(pre->right==nullptr){
		//TODO
		pre->rtag=1;
	}
}
tree trfind(tree&p){
	//线索化后的树,0代表孩子,1代表前驱
	treenode *res;
	if(p->rtag==0){
		//TODO
		res=p->right;
	}
	else if(p->ltag==0){res=p->left;}
	else if(p->left==nullptr){res=nullptr;}//整个树最左边结点
	else{
		//当左右孩子均为空时
		//后序前驱,是中序线索树中该结点前驱的左孩子
		while(p->ltag==1&&p->left!=nullptr){
			//TODO
			p=p->left;//不断往上查找,p->left==nullptr,也是在考虑最左结点
		}
		if(p->ltag==0){res=p->left;}
		else{res=nullptr;}//最左边结点
	}
	return res;
}
int main(){
	tree root;
	create(root);
	tree t=root;
	start_inorder(t);
	tree res=trfind(root->right);
	cout<<res->data<<endl;
	return 0;
}

查找

二分查找递归

//二分查找的递归写法
#include<bits/stdc++.h>
using namespace std;
int b_search(vector<int> test,int l,int r,int x){
	if(l>r){
		//TODO
		return -1;
	}
	int mid=(l+r)/2;
	if(x>test[mid]){
		//TODO
		return b_search(test,mid+1,r,x);
	}
	else if(x<test[mid]){
		//TODO
		return b_search(test,l,mid-1,x);
	}
	else{
		return mid;
	}
}
int main(){
	vector<int> test;
	for(int i=0;i<=10;i++){
		//TODO
		test.push_back(i);
	}
	cout<<b_search(test,1,test.size(),5);
	return 0;
}

bfs最短路径

//bfs单源最短路径
#include<bits/stdc++.h>
using namespace std;
#define maxv 4
#define maxsize 100
//定义图的结构体
struct graph{
	int vnum;
	char name[4];
	int a[4][4];
	graph():vnum(4),name{'A','B','C','D'},a{
	{0,1,9999,9999},
	{1,0,1,1},
	{9999,1,0,9999},
	{9999,1,9999,0}}{}
};
vector<bool> visited(4);
typedef struct graph graph;
struct myque{
	int v[100];
	int f,r,tag;
	myque():f(0),r(0),tag(0){}
};
typedef struct myque myque;
int qsize(myque q){return (maxsize-(q.f-q.r))%maxsize;}
bool qfull(myque q){return q.f==q.r&&q.tag==1;}
bool qnone(myque q){return q.f==q.r&&q.tag==0;}
bool pushque(myque &q,int &i){
	if(qfull(q)){
		//TODO
		cout<<"队列已满"<<endl;
		return false;
	}
	q.v[q.r]=i;
	q.r=(q.r+1)%maxsize;
	return true;
}
bool popque(myque &q,int&i){
	if(qnone(q)){
		cout<<"队列已空"<<endl;
		return false;
	}
	i=q.v[q.f];
	q.f=(q.f+1)%maxsize;
	return true;
}
int path[4];
int prevex[4];
void bfs(graph g,int num){
	for(int i=0;i<g.vnum;i++){
		//TODO
		path[i]=9999;
		prevex[i]=-1;
	}
	myque q;
	prevex[num]=num;
	path[num]=0;
	visited[num]=true;
	pushque(q,num);
	while(qsize(q)>0){
		//TODO
		popque(q,num);
		for(int i=0;i<g.vnum;i++){
			//TODO
			if(visited[i]==0&&g.a[num][i]!=9999){
				//TODO
				path[i]=path[num]+1;
				prevex[i]=num;
				visited[i]=true;
				pushque(q,i);
			}
		}
	}
}
int main(){
	graph g;
	bfs(g,0);
	for(int i=0;i<4;i++){
		//TODO
		cout<<path[i]<<" ";
	}
	return 0;
}

dfs逆拓扑

//dfs实现逆拓扑序列和拓扑序列AOV
#include<bits/stdc++.h>
using namespace std;
struct graph{
	int vnum;
	int edge[5][5];
	graph():vnum(5),edge{
	{0,1,9999,9999,9999},
	{9999,0,9999,1,9999},
	{9999,9999,0,1,1},
	{9999,9999,9999,0,1},
	{9999,9999,9999,9999,0}}{}
};
typedef struct graph graph;
bool visited[5];
void dfs(graph g,int m){
	visited[m]=true;
	for(int i=0;i<5;i++){
		//TODO
		if(visited[i]==0&&g.edge[m][i]!=9999&&g.edge[m][i]!=0){
			//TODO
			dfs(g,i);
		}
	}
	cout<<m<<" ";
}
void dfsall(graph g){
	for(int i=0;i<5;i++){
		//TODO
		visited[i]=false;
	}
	for(int i=0;i<5;i++){
		//TODO
		if(visited[i]==0){
			//TODO
			dfs(g,i);
		}
	}
}
int main(){
	graph g;
	dfsall(g);
	
	return 0;
}

最小生成树

//最小生成树prim&&kruskal
#include<bits/stdc++.h>
using namespace std;
#define maxv 6
struct graph{
	int vnum;
	char name[6];
	int edge[maxv][maxv];
	graph():vnum(6),name{'X','Y','Z','O','P','Q'},edge{
	{0,6,5,1,9999,9999},
	{6,0,9999,5,3,9999},
	{5,9999,0,4,9999,2},
	{1,5,4,0,6,4},
	{9999,3,9999,6,0,6},
	{9999,9999,2,4,6,0}}{}
};
typedef struct graph graph;
void prim(graph g){
	int lowcost[6];//存储到达6个点的花费代价
	int adjvex[6];//存储最后6条边的起点
	//把第一条边加入

	for(int i=1;i<g.vnum;i++){
		//TODO
		lowcost[i]=g.edge[0][i];
		adjvex[i]=0;//起初起点都是0,避免找不到顶点
	}
	//开始一行行查找最小的代价,并把它加入

	for(int i=1;i<g.vnum;i++){
		int minedge=9999,minvex;
		int k=1;
		while(k<g.vnum){
			//TODO
			if((lowcost[k]!=0)&&lowcost[k]<minedge){
				//TODO
				minedge=lowcost[k];
				minvex=k;
			}
			k++;
		}

		//找到此时能到达花费代价最小的边
		//更新图中信息
		lowcost[minvex]=0;
		//每确定一个点就将和他相连的边打印出来
		cout<<"("<<g.name[adjvex[minvex]]<<","<<g.name[minvex]<<")"<<" ";
		//更新图
		for(int j=1;j<g.vnum;j++){
			//TODO
			if((lowcost[j]!=0)&&g.edge[minvex][j]<lowcost[j]){
				//TODO
				lowcost[j]=g.edge[minvex][j];
				adjvex[j]=minvex;
			}
		}

	}
}
int main(){
	graph g;
	prim(g);
	return 0;
}
/*int Find(int *parent, int f) {
while (parent[f] > 0) {
f = parent[f];//如果f点有其他的终点,将其返回
}
return f;
}


void MiniSpanTree_Kruskal(MGraph G) {
int i, j, n, m, k;
Edge edges[G.numEdges];
int parent[G.numVertexes];

//******************adjacency Matrix to Edges Array********************
k = 0;
for (i = 0; i < G.numVertexes; i++) {
for (j = (i + 1); j < G.numVertexes; j++) { /*undigraph just deal with upper triangle Matrix*/
/*if (G.arc[i][j] != INFINITY) {
edges[k].weight = G.arc[i][j];
edges[k].begin = i;
edges[k].end = j;
k++;
}
}
}
//******************adjacency Matrix to Edges Array********************
//print the edge array.
//for(i=0;i<G.numEdges;i++)
//	{
//		printf("edge[%d]: begin: %d, end: %d, weight: %d \n",i,edges[i].begin,edges[i].end,edges[i].weight);
//	}

//************sort the edges array with bubble sorting method**********
Edge temp;
for (k = 1; k <= G.numEdges - 1; k++) {
for (i = 0; i < G.numEdges - k; i++) {
if (edges[i].weight > edges[i + 1].weight) {
temp = edges[i];
edges[i] = edges[i + 1];
edges[i + 1] = temp;
}

}
}//将边排序

//print the ordered edge array
//for(i=0;i<G.numEdges;i++)
//	{
//		printf("edge[%d]: begin: %d, end: %d, weight: %d \n",i,edges[i].begin,edges[i].end,edges[i].weight);
//	}
//************sort the edges array with bubble sorting method**********

for (i = 0; i < G.numVertexes; i++) {
parent[i] = 0;
}
printf("The minimum spanning tree is (Kruskal):\n");
for (i = 0; i < G.numEdges; i++) {
n = Find(parent, edges[i].begin);
m = Find(parent, edges[i].end);
if (n != m) {
parent[n] = m;
printf("[(%c,%c) %d] ", G.vexs[edges[i].begin], G.vexs[edges[i].end], edges[i].weight);
}
}
printf("\n");
}

 */

迪杰斯特拉单源最短路

//dijkstra算法

#include<bits/stdc++.h>
using namespace std;
struct graph{
	int vnum;
	string name[5];
	int edge[5][5];
	graph():vnum(5),name{"v0","v1","v2","v3","v4"},edge{
	{0,10,9999,7,5},
	{10,0,6,9999,2},
	{9999,6,0,6,9},
	{7,9999,6,0,2},
	{5,2,9,2,0}}{}
};
typedef struct graph graph;
int finded[5];
int path[5];
int prevex[5];
void dijkstra(graph g,int m){
	//初始化
	for(int i=0;i<g.vnum;i++){
		//TODO
		finded[i]=0;
		path[i]=g.edge[m][i];;
		prevex[i]=-1;
	}
	prevex[m]=m;
	finded[m]=1;
	for(int i=0;i<g.vnum;i++){
		//TODO
		int minedge=9999,minvex,j=0;
		while(j<g.vnum){
			//TODO
			if(finded[j]==0&&path[j]<minedge){
				//TODO
				minedge=path[j];
				minvex=j;
			}
			j++;
		}
		//找到一行中最少的路径
		//更新path,prevex,finded;
		finded[minvex]=1;
		for(int k=0;k<g.vnum;k++){
			//TODO
			if(finded[k]==0&&path[minvex]+g.edge[minvex][k]<path[k]){
				//TODO
				path[k]=path[minvex]+g.edge[minvex][k];
				prevex[k]=minvex;
			}
		}


	}
}
int main(){
	graph g;
	dijkstra(g,0);
	for(int i=0;i<g.vnum;i++){
		//TODO
		cout<<path[i]<<" ";
	}
	return 0;
}

dfs&&bfs

//图的深度优先遍历
#include<bits/stdc++.h>
using namespace std;
#define maxv 4
#define maxsize 100
//定义图的结构体
struct graph{
	int vnum;
	char name[4];
	int a[4][4];
	graph():vnum(4),name{'A','B','C','D'},a{
	{0,1,9999,9999},
	{1,0,1,1},
	{9999,1,0,9999},
	{9999,1,9999,0}}{}
};
vector<bool> visited(4);
typedef struct graph graph;
struct myque{
	int v[100];
	int f,r,tag;
	myque():f(0),r(0),tag(0){}
};
typedef struct myque myque;
int qsize(myque q){return (maxsize-(q.f-q.r))%maxsize;}
bool qfull(myque q){return q.f==q.r&&q.tag==1;}
bool qnone(myque q){return q.f==q.r&&q.tag==0;}
bool pushque(myque &q,int &i){
	if(qfull(q)){
		//TODO
		cout<<"队列已满"<<endl;
		return false;
	}
	q.v[q.r]=i;
	q.r=(q.r+1)%maxsize;
	return true;
}
bool popque(myque &q,int&i){
	if(qnone(q)){
		cout<<"队列已空"<<endl;
		return false;
	}
	i=q.v[q.f];
	q.f=(q.f+1)%maxsize;
	return true;
}
void dfs(graph g,int i){
	int j=0;
	visited[i]=1;//标志i结点已经访问过
	cout<<g.name[i]<<" ";
	for(j=0;j<g.vnum;j++){
		//TODO
		if(g.a[i][j]!=9999&&visited[j]==0){
			//TODO
			dfs(g,j);
		}
	}

}
void dfsall(graph g){
	//初始化,是否访问过标志数组
	for(int i=0;i<visited.size();i++){
		//TODO
		visited[i]=0;
	}
	for(int i=0;i<g.vnum;i++){
		//TODO
		if(!visited[i]){
			//TODO
			dfs(g,i);
		}
	}
}
void bfs(graph g,int i){
	myque q;
	visited[i]=1;
	cout<<g.name[i]<<" ";
	pushque(q,i);
	int j;
	while(qsize(q)>0){
		//TODO
		popque(q,i);

		for(j=0;j<g.vnum;j++){
			//TODO
			if(g.a[i][j]!=9999&&visited[j]==0){
				visited[j]=1;
				cout<<g.name[j]<<" ";
				pushque(q,j);
			}
		}
	}
}
void bfsall(graph g){
	//初始化
	for(int i=0;i<g.vnum;i++){
		//TODO
		visited[i]=0;
	}
	for(int i=0;i<g.vnum;i++){
		//TODO
		if(!visited[i]){

			bfs(g,i);//TODO
		}
	}
}
int v=0,edge=0;
void dfstest(graph g,int i){
	int j=0;
	visited[i]=1;//标志i结点已经访问过
	cout<<g.name[i]<<" ";
	v++;
	for(j=0;j<g.vnum;j++){
		//TODO
		if(g.a[i][j]!=9999&&g.a[i][j]!=0){
			//TODO
			edge++;
			if(visited[j]==0){
				//TODO
				dfstest(g,j);
			}

		}
	}
}
//判断图是否是树
bool istree(graph g){
	for(int i=0;i<visited.size();i++){
		//TODO
		visited[i]=0;
	}
	dfstest(g,0);
	cout<<v<<endl;
	cout<<edge<<endl;
	if(v==g.vnum&&edge==2*(g.vnum-1)){
		//TODO
		return true;
	}else{return false;}
}
int main(){
	graph g;
	cout<<g.a[2][2]<<endl;
	cout<<g.name[0]<<endl;
	//dfsall(g);
	cout<<endl;
	//bfsall(g);
	cout<<istree(g);
	return 0;
}

排序

插入排序

//插入排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void insertsort(myarray test){
	int j=1;
	while(j<test.size()){
		//TODO
		if(test[j-1]>test[j]){
			//TODO
			int temp=test[j];//小的前移
			int i=j-1;
			while(test[i]>temp&&i>=0){
				//TODO
				test[i+1]=test[i];
				i--;
			}
			test[i+1]=temp;
		}
		j++;
	}
	for(auto num:test){cout<<num<<" ";}
}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	insertsort(test);
	return 0;
}


二分查找&&插入排序

//优化插入排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void half_insert_sort(myarray test){
	int j=1;
	while(j<test.size()){
		//TODO
		if(test[j-1]>test[j]){
			//TODO
			int temp=test[j];
			int l=0,r=j-1;
			while(l<=r){
				//TODO
				int mid=(l+r)/2;
				if(test[mid]>temp){
					//TODO
					r=mid-1;
				}else{
					//mid 等于temp时,为保证稳定,所以l继续右移,是temp放在相等的值后面
					l=mid+1;
				}

			}
			//h指向插入位置的前一位
			//开始移动并插入
			int i=j-1;
			while(i>r&&i>=0){
				//TODO
				test[i+1]=test[i];
				i--;
			}
			test[r+1]=temp;
		}
		j++;
	}
	for(auto num:test){cout<<num<<" ";}
}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	half_insert_sort(test);
	return 0;
}

希尔排序

//希尔排序
//将数组分成若干个子表,进行插入排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void shellsort(myarray test){
	int d=test.size()/2;
	while(d>=1){
		//TODO
		int i=d;
		while(i<test.size()){
			//TODO
			if(test[i-d]>test[i]){
				//TODO
				int temp=test[i];
				int j=i-d;
				while(j>=0&&test[j]>temp){
					//TODO
					test[j+d]=test[j];
					j=j-d;
				}
				test[j+d]=temp;

			}
			i++;
		}
		d=d/2;
	}

	for(auto num:test){cout<<num<<" ";}
}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	shellsort(test);
	return 0;

堆排序

//堆排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void adjust(myarray&test,int root,int len){
	int l=2*root;
	int r=2*root+1;
	int maxwhere=root;
	if(l<len&&test[maxwhere]<test[l]){
		//TODO
		maxwhere=l;
	}
	if(r<len&&test[maxwhere]<test[r]){
		//TODO
		maxwhere=r;
	}
	//连续两个if找出三个数值最大的下标
	if(maxwhere!=root){
		//TODO
		swap(test[root],test[maxwhere]);//交互,但是下标没有变化
		//交换后,max指向的就不是最大值了,而是背换下来的值,会对下一层产生影响,所以向下一层递归
		adjust(test,maxwhere,len);
	}
}
void heapsort(myarray&test){
	int maxwhere=(int)(9/2);
	for(int i=maxwhere;i>=0;i--){
		//TODO
		adjust(test,i,8);
	}//建堆就是第一次调整,for循环表示从下往上调整,调整函数里由上往下


	//开始排序
	for(int i=8;i>=0;i--){
		//TODO
		cout<<test[0]<<" ";
		swap(test[0],test[i]);
		adjust(test,0,i-1);
	}

}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	heapsort(test);
	return 0;
}

选择排序

//简单选择排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void simple_select_sort(myarray test){
	int i=0;
	while(i<test.size()){
		//TODO
		int minnum=test[i];
		int j=i+1;
		while(j<test.size()){
			//TODO
			if(minnum>test[j]){
				//TODO
				int temp=minnum;
				minnum=test[j];
				//这里test[j]必须赋值,把未排序的数储存
				test[j]=temp;
			}
			j++;
		}
		test[i]=minnum;
		i++;
	}
	for(auto num:test){cout<<num<<" ";}
}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	simple_select_sort(test);
	return 0;
}

归并排序

//归并排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;

myarray test{1,2,3,4,5,6,7,2};
myarray help(test.size(),0);
void mysort(myarray&test,int l,int r,int divd){
	int k=0;
	while(k<test.size()){
		//TODO
		help[k]=test[k];
		k++;
	}
	int i=0,j=divd+1;
	k=0;
	for(;i<=divd&&j<=r;k++){
		//TODO
		if(help[i]<=help[j]){
			//TODO
			test[k]=help[i];
			i++;
		}else{
			test[k]=help[j];
			j++;
		}

	}

	//是否有剩余
	while(i<=divd){
		//TODO
		test[k]=help[i];
		i++;
		k++;
	}
	while(j<=r){
		//TODO
		test[k]=help[j];
		j++;
		k++;
	}

}
void mydivid(myarray&test,int l,int r){
	if(l<r){
		//TODO
		int mid=(l+r)/2;

		//先分
		mydivid(test,l,mid);
		mydivid(test,mid+1,r);


		//再排,合并时必须知道从那间隔
		mysort(test,l,r,mid);
	}
}
int main(){
	mydivid(test,0,test.size()-1);
	for(auto num:test){cout<<num<<" ";}
	return 0;
}

快速排序

//快速排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
int findpos(myarray&test,int l,int r){
	int temp=test[l];
	while(l<r){
		while(l<r&&test[r]>=temp){
			r--;
		}
		test[l]=test[r];
		while(l<r&&test[l]<=temp){
			//TODO
			l++;
		}
		test[r]=test[l];
	}
	test[l]=temp;
	//for(auto num:test){cout<<num<<" ";}
	//cout<<endl;
	return l;

}
void fastsort(myarray&test,int l,int r){
	if(l<r){
		int pos=findpos(test,l,r);
		fastsort(test,l,pos-1);
		fastsort(test,pos+1,r);

	}

}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	fastsort(test,0,test.size()-1);
	for(auto num:test){cout<<num<<" ";}
	return 0;
}

奇数前偶数后

//奇数前,偶数后
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void fastsort_2(myarray test){
	int l=0,r=test.size()-1;
	//左边找偶数
	//右边找奇数,然后交换
	while(l<r){
		//TODO
		while(l<r&&test[l]%2!=0){
			//TODO
			l++;
		}
		while(l<r&&test[r]%2==0){
			//TODO
			r--;
		}
		if(l<r){
			//TODO
			swap(test[l],test[r]);
			l++;
			r--;
		}
	}
	for(auto num:test){cout<<num<<" ";}
}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	fastsort_2(test);
}

冒泡排序

//冒泡排序
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void bubble_sort(myarray &test){
	int i=0;
	while(i<test.size()){
		//TODO
		bool flag=false;
		int j=test.size()-1;
		while(j>i){
			//TODO
			if(test[j-1]>test[j]){
				//TODO
				int temp=test[j-1];
				test[j-1]=test[j];
				test[j]=temp;
				flag=true;
			}

			j--;
		}
		if(flag==false){
			//TODO
			for(auto num:test){cout<<num<<" ";}
			return;
		}
		i++;
	}
}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	bubble_sort(test);
	return 0;
}

双冒泡排序

//双冒泡排序,每次遍历一趟,确定一个最大值和最小值
//low左边是确定的最小值,high右边是确定的最大值
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> myarray;
void duble_bubble_sort(myarray test){
	int l=0, r=test.size()-1;
	bool flag=true;
	while(l<r&&flag){
		//TODO
		flag=false;//表示一开始没有发生变化
		for(int i=l;i<r;i++){
			//TODO
			if(test[i]>test[i+1]){
				//TODO
				int temp=test[i];
				test[i]=test[i+1];
				test[i+1]=temp;
				flag =true;
			}
		}
		r--;
		//最大值确定一个,从左到右



		for(int i=r;i>l;i--){
			//TODO
			if(test[i-1]>test[i]){
				//TODO
				int temp=test[i-1];
				test[i-1]=test[i];
				test[i]=temp;
				flag=true;
			}
		}
		l++;
		//最小值确定一个
	}
	for(auto num:test){cout<<num<<" ";}
}
int main(){
	myarray test{4,532,44,2323,44350,1,4,24,333};
	duble_bubble_sort(test);
	return 0;
}
posted @ 2023-04-04 13:42  jinganglang567  阅读(13)  评论(0)    收藏  举报