常用数据结构持续更新

1.链表

/*链表测试*
  int类型 * 
  单链表  */
#include<bits/stdc++.h>

using namespace std;
struct node{
    int key;
    node *next;//指向下一个节点
};
typedef node *ptrnode;
typedef ptrnode List;
typedef ptrnode pos;
int isempty(List L){//判空函数
    return L->next==NULL;
}
int islast(pos P,List L){//判断是否是最后一个元素;
    return P->next==NULL;
}
pos find(List L,int element){//查找元素位置;
    pos p=L;
    while(p !=NULL and p->key!=element){
        p=p->next;
    }
    if(p->key==element ) return p;
    return NULL;
}
pos findpre(List L,int element){//寻找ele的前驱位置;
    pos p=L;
    while(p->next !=NULL and p->next->key!=element){
        p=p->next;
    }
    if(p->next->key==element ) return p;
    return NULL;
}
void Delete(List L,int element){//删除一个元素;
    pos tem;
    pos p=findpre(L,element);
    if(!islast(p,L)){
        tem=p->next;
        p->next=tem->next;
        free(tem);
    }
}
void Insert(List L,int element,pos p){//指定位置插入元素;
    pos tem;
    tem=(ptrnode)malloc(sizeof(node));
    if(tem==NULL)//空间溢出;
    return;
    tem->key=element;
    tem->next=p->next;
    p->next=tem;
}
void Deletelist(List L){//删除整个链表;
    pos p,tem;
    p=L->next;
    L->next=NULL;
    while(p!=NULL){
        tem=p->next;
        free(p);
        p=tem;
    }
}
void Travel(List L){//遍历链表;
    pos p;
    
    p=L->next;
    while(p!=NULL){
        cout<<p->key<<endl;//输出值;
        p=p->next;
    }
}
void Insert_head(List L,int element){//头插;
    pos tem=(ptrnode)malloc(sizeof(node));
    tem->key=element;
    tem->next=L->next;
    L->next=tem;
}
int main(){//测试
    List L;
    L->next=NULL;
    
    for(int i=1;i<=10;i++){
        Insert_head(L,i);
        
    }
    Travel(L);
    Delete(L,5);//删除值为5的节点;
    Travel(L);
    pos p=find(L,3);//找到值为3的节点
    Insert(L,5,p);//在3的后面插入一个节点,值为5;
    Travel(L);
    




    return 0;
}

(2)双链表

#include<bits/stdc++.h>

using namespace std;
/*双向链表
 int 类型
 test*/
struct node{
    int key;
    node *next;
    node *prev;
};
typedef node *ptrnode;
typedef ptrnode List;
typedef ptrnode pos;
bool isempty(List L){//判空;
    return L->next==NULL;
}
bool islast(List L,pos P){//判断是否是最后一个;
    return P->next==NULL;
}
pos find(List L,int element){//查找元素位置;
    pos p=L;
    while(p->next!=NULL and p->key!=element){
        p=p->next;
    }
    return p;
}
void Insert(List L,int element,pos p){//按照指定位置插入;
    pos tem=(ptrnode)malloc(sizeof(node));
    tem->key=element;
    tem->prev=p;
    tem->next=p->next;
    p->next->prev=tem;
    p->next=tem;
}
void Delete(List L,int element){//删除指定元素;
    pos p=find(L,element);
    p->prev->next=p->next;
    p->next->prev=p->prev;
    free(p);
}
void Insert_head(List L,int element){//头插法;
    pos tem=(ptrnode)malloc(sizeof(node));
    tem->key=element;
    tem->next=L->next;
    if(L->next!=NULL) L->next->prev=tem;//这里需要注意,假如是第一个插入的元素,则不需要进行这个操作,所以需要特判;
    tem->prev=L;
    L->next=tem;
}
void Travel_right(List L){//正序遍历;
    pos p=L->next;
    while(p!=NULL){
        cout<<p->key<<endl;
        p=p->next;
    }
}
int main(){//测试;
    List L;
    L->next=L->prev=NULL;
    for(int i=1;i<=5;i++){
        Insert_head(L,i);
    }
    Travel_right(L);
    Delete(L,4);
    Travel_right(L);
    pos p=find(L,5);
    // cout<<p->key<<endl;
    // cout<<p->prev->key<<endl;
    Insert(L,4,p);
    Travel_right(L);
    return 0;
}

3.二叉树

/*树_二叉查找树;
test*/
/*二叉查找树性质:
对于一个节点,他的左子树的值小于这个节点的值,
右节点与之相反;*/
#include<bits/stdc++.h>

using namespace std;
/*二叉树建立方式:
完全二叉树可以使用一维数组实现;
其中x的两个子节点分别为2x和2x+1;
比如一共有n个节点,最后一个节点的父节点就是
n/2;
还有一种静态链表的建立方式:
struct node{
   int key;
   int left;
   int right; 
}a[node_max];
其中left和right存储的分别是
这个节点的子节点的下标;
*/
struct node{
    int key;
    node *left;
    node *right;
};
typedef node *ptrnode;
typedef ptrnode tree;
typedef ptrnode pos;
tree empty_tree(tree T){//建立一颗空树;
    if(T!=NULL){
        empty_tree(T->left);
        empty_tree(T->right);
        free(T);
    }
    return NULL;
}
pos find(int element,tree T){//查找一个元素的位置;
    if(T==NULL) return NULL;
    if(element<T->key)
        return find(element,T->left);
    else if(element>T->key){
        return find(element,T->right);
    }
    else return T;
}
/*因为这种递归方式称为尾递归,所以可以使用非递归实现
//基本框架:
    while(T){
    if(x<T->key){
        T=T->left;
    }
    if(x>T->key){
        T=T->right;
    }
    else 
    return T;
}*/
pos find_min(tree T){//寻找最小值
    if(T==NULL) return NULL;
    else if(T->left==NULL) return T;
    else return find_min(T->left);
}
pos find_max(tree T){//寻找最大值;
    if(T==NULL) return T;
    else if(T->right==NULL) return T;
    else return find_max(T);
}
tree Insert(tree T,int element){
    if(T==NULL){
        T=(ptrnode)malloc(sizeof (node));
        T->key=element;
        T->left=T->right=NULL;
    }
    else if(element<T->key)
        T->left=Insert(T->left,element);
    else if(element>T->key)
        T->right=Insert(T->right,element);
    return T;
}
tree Delete(tree T,int element){
    pos tem;
    //if(T==NULL)
    if(element<T->key){
        T->left=Delete(T->left,element);
    }
    else if(element>T->key){
        T->right=Delete(T->right,element);
    }
    else if(T->left and T->right){//这个节点有两个子节点的情况;
        tem=find_min(T->right);//找到编号最小的右子树;
        T->key=tem->key;//替换;
        T->right=Delete(T->right,T->key);//删除掉这个节点;
    }
    else{//只有一个子节点的情况;
        tem=T;
        if(T->left==NULL) T=T->right;
        else if(T->right) T=T->left;
        free(tem);
    }
    return T;
}
void Print(tree T){//输出键值;
    cout<<T->key<<endl;
}

void Travel(tree T){//先序遍历;
    if(T!=NULL){
        Print(T);
        Travel(T->left);
        Travel(T->right);
    }
}
/*先序遍历即先访问根节点然后访问左子树然后右子树;
	中序:先访问左子树然后根节点然后右子树;
	后序遍历:先访问左子树,然后右子树,然后根节点;


*/
int main(){
    tree T=NULL;
    for(int i=5;i<=10;i++){
        T=Insert(T,i);
    }
    for(int i=1;i<=4;i++){
        T=Insert(T,i);
    }
    Travel(T);// /
    // T=Delete(T,6);
    // Travel(T);
    return  0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值