数据结构
顺序表
快慢指针删除重复元素
#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;
}