目录
1 二叉树
1:二叉树初始化
2:二叉树的创建
3:先序遍历
4:中序遍历
5:后序遍历
6:打印
#include <bits/stdc++.h>
using namespace std;
class BinaryTree//二叉树的初始化
{
public:
char data;
BinaryTree* left;
BinaryTree* right;
};
void CreatBinaryTree(BinaryTree* &root)//二叉树的创建
{
char c;
cin>>c;
if(c=='#') root=NULL;
else
{
root=new BinaryTree;
root->data=c;
CreatBinaryTree(root->left);
CreatBinaryTree(root->right);
}
}
void Preorder(BinaryTree* root,vector<char> &path)//先序遍历
{
if(root!=NULL)
{
path.push_back(root->data);
Preorder(root->left,path);
Preorder(root->right,path);
}
}
void Inorder(BinaryTree* root,vector<char> &path)//中序遍历
{
if(root!=NULL)
{
Preorder(root->left,path);
path.push_back(root->data);
Preorder(root->right,path);
}
}
void Postorder(BinaryTree* root,vector<char> &path)//后序遍历
{
if(root!=NULL)
{
Preorder(root->left,path);
Preorder(root->right,path);
path.push_back(root->data);
}
}
void PrintBinaryTree(vector<char> path)
{
int n=path.size();
for(int i=0;i<n;i++)
{
cout<<path[i]<<' ';
}
cout<<endl;
}
int main()
{
vector<char> path1,path2,path3;
BinaryTree* root=NULL;
CreatBinaryTree(root);
Preorder(root,path1);
PrintBinaryTree(path2);
Inorder(root,path2);
PrintBinaryTree(path2);
Postorder(root,path3);
PrintBinaryTree(path3);
return 0;
}
2 二叉搜索树
1:创建结点
2:创建树
3:中序遍历
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
typedef struct Node Node;
Node *CreatBSTree(Node* root,int num)
{
if(root==NULL)
{
root=(Node*)malloc(sizeof(Node));
if(root==NULL)
{
return NULL;
}
root->data=num;
root->left=NULL;
root->right=NULL;
}
else
{
if(root->data>num) root->left=CreatBSTree(root->left,num);
else root->right=CreatBSTree(root->right,num);
}
return root;
}
void Inorder(Node *root)
{
if(root==NULL) return;
Inorder(root->left);
cout<<root->data<<' ';
Inorder(root->right);
}
int main()
{
int i,num;
Node* root=NULL;
for(i=0;i<10;i++)
{
cin>>num;
root=CreatBSTree(root,num);
}
Inorder(root);
return 0;
}
3 最小生成树
3.1 Prim算法
#include <bits/stdc++.h>
using namespace std;
int main()
{
int points,edges,xiao;//points结点数 edges道路总数 xiao最小值
int edge[7][7];//欧氏距离
int dist[7];
bool flag[7];//记忆化
cin>>points>>edges;
for(int i=1;i<=points;i++)//edge[][]的初始化及存储
{
for(int j=1;j<=points;j++)
{
if(i==j) edge[i][j]=0;
else edge[i][j]=INT_MAX;
}
}
int p1,p2,w;
for(int i=1;i<=edges;i++)
{
cin>>p1>>p2>>w;
edge[p1][p2]=w;
edge[p2][p1]=w;
}
for(int i=1;i<=points;i++)//初始化一号顶点到其他顶点的距离
{
dist[i]=edge[1][i];
}
flag[1]=true;
int cnt=1,j,sum;
while(cnt<points)//边界是连接了所有的点
{
xiao=INT_MAX;
for(int i=1;i<=points;i++)
{
if(!flag[i]&&dist[i]<xiao)
{
xiao=dist[i];
j=i;//记住连接了第几个点
}
}
flag[j]=true;
cnt++;
sum=sum+dist[j];
for(int i=1;i<=points;i++)
{
if(!flag[i]&&dist[i]>edge[j][i]) dist[i]=edge[j][i];
}
}
cout<<sum;
return 0;
}
3.2 Kruskal算法
#include <bits/stdc++.h>
using namespace std;
int fa[100000];
struct edge
{
int u;//左端点
int v;//右端点
int dist;//距离
}ed[100000];
bool cmp(edge a,edge b)
{
return a.dist<b.dist;
}
void init(int n)
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
}
}
int find(int x)
{
if(x==fa[x]) return x;
int temp=find(fa[x]);
return temp;
}
int kruskal(int n,int m)
{
int ans,cnt;
for(int i=0;i<m;i++)
{
int fu=find(ed[i].u);
int fv=find(ed[i].v);
if(fu!=fv)
{
fa[fu]=fv;
ans=ans+ed[i].dist;
cnt++;
if(cnt==n-1) break;
}
}
if(cnt!=n-1) return -1;
else return ans;
}
int main()
{
int n,m;
cin>>n>>m;
init(n);
for(int i=0;i<m;i++)
{
cin>>ed[i].u>>ed[i].v>>ed[i].dist;
}
sort(ed,ed+m,cmp);
cout<<kruskal(n,m);
return 0;
}
如要详细了解各个算法的原理,请移步:图论(入门版)_菜只因C的博客-CSDN博客图论(入门版)https://blog.csdn.net/m0_71934846/article/details/128757672?spm=1001.2014.3001.5501
4 AVL树(难)
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <ctime>
using namespace std;
typedef struct Node {
int value, h;
struct Node *left, *right;
} Node;
Node __NIL;
#define NIL (&__NIL)
__attribute__((constructor))
void init_NIL() {
NIL->value = -1;
NIL->left = NIL->right = NIL;
NIL->h = 0;
return ;
}
Node *getNewNode(int value) {
Node *p = (Node *)malloc(sizeof(Node));
p->value = value;
p->left = p->right = NIL;
p->h = 1;
return p;
}
void update_h(Node *root) {
root->h = max(root->left->h, root->right->h) + 1;
return ;
}
/// AVL树 核心部分/
//左旋,root为要旋转节点的父节点
Node *left_rotate(Node *root) {
Node *tmp = root->right;//保存要左旋节点为根节点的节点
root->right = tmp->left;//原先的根节点的右子节点存左旋节点的左节点,这样就不会出现三叉树了
tmp->left = root;//如果调整右旋节点为根节点
//更新树高
update_h(root);
update_h(tmp);
return tmp;
}
//右旋
Node *right_rotate(Node *root) {
Node *tmp = root->left;
root->left = tmp->right;
tmp->right = root;
update_h(root);
update_h(tmp);
return tmp;
}
//判断失衡类型
Node *maitain(Node *root) {
if (abs(root->left->h - root->right->h) <= 1) return root;
if (root->left->h > root->right->h) {//左子树更高,失衡条件是L
if (root->left->right->h > root->left->left->h) {
root->left = left_rotate(root->left);//LR
}
root = right_rotate(root);//LL
} else {
//右子树更高,失衡条件是R
if (root->right->left->h > root->right->right->h) {
root->right = right_rotate(root->right);//RL
}
root = left_rotate(root);//RR
}
return root;
}
Node *insert(Node *root, int target) {
if (root == NIL) return getNewNode(target);
if (root->value == target) return root;
if (root->value > target) {
root->left = insert(root->left, target);
} else {
root->right = insert(root->right, target);
}
update_h(root);
return maitain(root);//递归时判断失衡且调整
}
Node *get_pre(Node *root) {
Node *tmp = root;
while (tmp->right != NIL) {
tmp = tmp->right;
}
return tmp;
}
Node *erase(Node *root, int target) {
if (root == NIL) return root;
if (root->value > target) {
root->left = erase(root->left, target);
} else if (root->value <target) {
root->right = erase(root->right, target);
} else {
if (root->left == NIL && root->right == NIL) {
free(root);
return NIL;
} else if (root->left == NIL || root->right == NIL) {
Node *tmp = (root->left != NIL ? root->left : root->right);
free(root);
return tmp;
} else {
Node *tmp = get_pre(root->left);
root->value = tmp->value;
root->left = erase(root->left, tmp->value);
}
}
update_h(root);
return maitain(root);//递归时判断失衡且调整
}
void clear(Node *root) {
if (root == NIL) return ;
clear(root->left);
clear(root->right);
free(root);
return ;
}
void out_put(Node *root) {
if (root == NIL) return ;
out_put(root->left);
printf("%d(%d) | %d, %d\n", root->value, root->h, root->left->value, root->right->value);
out_put(root->right);
return ;
}
int main()
{
srand(time(0));
Node *root = NIL;
int n = 5;
for (int i = 0; i < n; i++) {
int val = rand() % 100;
printf("\n insert %d to BST: \n", val);
root = insert(root, val);
out_put(root);
}
clear(root);
return 0;
}
5 线段树(难)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Maxsize 1000001
#define ll long long
using namespace std;
int m,n,a[Maxsize];
struct node {
int l;
int r;
ll sum;
ll lazy;
}tree[Maxsize];
void push_up(int k){
//根据k节点的两个孩子更新k节点
tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
void build (int k,int l,int r){
//初始化建树
// cout<<"build\n";
tree[k].l=l;
tree[k].r=r;
tree[k].lazy=0;
//cout<<"r: "<<tree[k].r<<" l: "<<tree[k].l<<" sum:"<<tree[k].sum<<endl;
if(l==r){
tree[k].sum=a[l];
return ;//递归结束
}
int mid=(l+r)/2;
build(2*k,l,mid);
build(2*k+1,mid+1,r);
push_up(k);
}
void push_down(int k,int l,int r){
//判断当前节点k有无lazy标记,将lazy标记向左右孩子传递
if(tree[k].lazy){
int mid=(l+r)/2;
tree[k<<1].lazy+=tree[k].lazy;
tree[k<<1|1].lazy+=tree[k].lazy;
tree[k<<1].sum+=tree[k].lazy*(tree[k*2].r-tree[k*2].l+1);
tree[k<<1|1].sum+=tree[k].lazy*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].lazy=0;
}
}
void change (int k,int l,int r,int x){
//区间更改,更改l[l~r]区间的数值+x
// cout<<endl<<"change"<<endl;
// cout<<"l:"<<tree[k].l<<" r:"<<tree[k].r<<endl;
if(l<=tree[k].l&&tree[k].r<=r){
tree[k].sum+=(long long)(tree[k].r-tree[k].l+1)*x;
tree[k].lazy+=x;
// cout<<" sum:"<<tree[k].sum<<endl;
return ;
}
push_down(k,tree[k].l,tree[k].r);
int mid=(tree[k].l+tree[k].r)/2;
if(l<=mid){
change(2*k,l,r,x);
}
if(r>mid){
change(2*k+1,l,r,x);
}
push_up(k);
// cout<<" sum:"<<tree[k].sum<<endl;
}
ll query (int k,int l,int r){
//当前节点位k,查询区间[l~r]
if(l<=tree[k].l&&tree[k].r<=r){
return tree[k].sum;
}
push_down(k,l,r);//当前区间不满足,继续向下遍历
//若进行单点修改不需要进行这一步,进行区间修改必须进行
ll res=0;
int mid=(tree[k].l+tree[k].r)/2;
if(l<=mid){
res+=query(k*2,l,r);
}
if(r>mid){
res+=query(k*2+1,l,r);
}
return res;
}
void update(int k,int x,int temp){
if(tree[k].r==tree[k].l){
tree[k].sum=temp;
return ;
}
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid){
update(2*k,x,temp);
}
else{
update(2*k+1,x,temp);
}
push_up(k);
}
int main (){
scanf("%d %d",&m,&n);
for(int i=1;i<=m;i++){
scanf("%d",&a[i]);
}
build(1,1,m);
for(int i=1;i<=n;i++){
int choice;
scanf("%d",&choice);
if(choice==2){
int l,r;
scanf("%d %d",&l,&r);
printf("%ld\n",query(1,l,r));
}
else{
int l,r,t;
scanf("%d %d %d",&l,&r,&t);
change(1,l,r,t);
}
// cout<<"\ndi: "<<i<<endl;
// for(int j=1;j<=n;j++){
// cout<<tree[j].sum<<" "<<tree[j].lazy<<";";
// }
}
return 0;
}