数据结构笔记(实现代码含注释)

  线性表
————————————————————————
 li2.1两个线性表的整合
void union(List &La,List Lb){
//先求出两表的长度
    La_len=ListLength(La);
    Lb_len=ListLength(Lb);
    for(int i=1;i<=Lb_len;i++){
        GetElem(Lb,i,e);
        if(!LocalElem(La,e,equal)){//Lb中的元素没有和La中的相等
            ListInsert(La,++La_len,e);        
        }
    }
}//union
li2.2归并算法
//前提是两个线性表都是非递减排列

void MergeList(List La,List Lb,List &Lc){
    InitList(Lc);
    int i=1,j=1,k=0;
    La_len=ListLength(La);
    Lb_len=ListLength(Lb);
    while((i<=La_len)&&(j<=Lb_len)){
        GetElem(La,i,ai);
        GetElem(Lb,j,bj);
        if(ai<=bj){
             ListInsert(Lc,++k,ai);
              i++;    
        }else{
              ListInsert(Lc,++k,bj);
              j++;
        }
    }
    while(i<=La_len){
                                 GetElem(La,i++,ai);
        ListInsert(Lc,++k,ai);
    }
    while(j<=Lb_len){
        GetElem(Lb,j++,bj);
        ListInsert(Lc,++k,bj);
    }    
}//MergeList

//动态数组
#define LIST_INIT_SIZE 100
#difine INITINCREMENT 10
typedef struct{
    ElemType *elem;
    int length;
    int listsize;
}Sqlist
Status InitList_Sq(Sqlist &L){
    L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(!L.elem)
         exit(OVERFLOW);//数据溢出
    L.length=0;
    L.listsize=LIST_INIT_SIZE;
    return OK;
}//InistList_Sq

 li2.3线性表的元素插入
Status ListInsert_Sq(SqList &L,int i,ElemType e){
    if(i<1||i>L.length+1)
        return ERROR;
    if(L.length>=L.Listsize){
        newbases=(ElemType *)realloc(L.elem,(L.Listsize+INCREMENT)*sizeof(ElemType));
        if(!newbases)
               exit(OVERFLOW);
        L.elem=newbases;
        L.listsize+=LISTINITCERMENT;
    }
    q=&(L.elem[i-1]);
    for(p=&(L.elem[L.length-1]);p>=q;p--){
          *(p+1)=*p;    
    }
    *q=e;
    ++L.length;
         return OK;

li2.4线性表的元素删除
Status ListDelete_Sq(SqList &L,int i,ElemType &e){
    if(i<1||i>L.length)
        return ERROR;
      p=&(L.elem[i-1]);
    e=*p;
    q=&(L.elem[L.length-1])
    for(++p;p<=q;++p){
        *(p-1)=*p;
    }
    --L.length;
    return OK;
}//ListDelete_Sq

li2.5定位元素位置
status LocalElem_Sq(Sqlist L,int i,Status(*compare)(ElemType,ElemType)){
    i=1;
    p=L.elem;
    while(i<=L.length&&!(*compare)(*p++,e))
        ++i;
    if(i<=L.length){//查找成功
                       return i;
    }else//查找失败
          return 0;
}//LocalElem_Sq

li2.6归并算法(指针版)
void MergeList(Sqlist La,Sqlist Lb,Sqlist &Lc){
    pa=La.elem;
    pb=Lb.elem;
    Lc.listsize=Lc.length=La.length+Lb.length;
    pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(Elemtype));
    if(!Lc.elem)
         exit(OVERFLOW);
    pa_last=La.elem+La.length-1;//这里pa_last指的是尾指针,相当于&(La.elme[La.length-1])
            pb_last=Lb.elem+Lb.length-1;
    while(pa<=pa_last&&pb<=pb_last){
        if(*pa<=*pb)
              *pc++=*pa++;
        else
               *pc++=*pb++;
    }
    while(pa<=pa_last)
        *pc++=*pa++;
    while(pb<=pb_lase)
        *pc++=*pb++;
}//MergeList_Sq


链表
————————————————————

li 2.7
//线性表的单链表存储结构
typedef struct LNode{
    ElemType data;
     struct LNode *next;
}LNode,*LinkList;

//在链表中获取元素
Status GetElem_L(LinkList L,int i,ElemType &e){
    //L为头指针
    p=L->next;
    j=1;//计数器
    while(p&&j<i){
          p=p->next;
           j++;
    }
    if(!p||j>i)
        return ERROR;
    else
         e=p->data;
    return OK;
}//GetElem_L

//在链表中插入元素
Status ListInsert_L(LinkList &L,int i,ElemType e){
          p=L;
    j=0;//这里查找元素方式不同是因为包含了是第一个元素的情况,也可以用之前查找元素的方法,但是要多加判断两种情况
    while(p&&j<i-1){
        p=p->next;
        j++;
    }
    if(!p||j>i-1)
               return ERROR;
    s=(LinkList)malloc(sizeiof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return OK;
}//LinkInsert_L

//在链表中删除元素
Status LinkDelete_L(LinkList &L,int i,ElemType &e){
    p=L;
    j=0;
    while((p->next)&&j<i-1){//这里因为查找的是第i-1个元素,来删除后面一个元素,所以后面一个元素必须存在,所以是p->next
          p=p->next;
          j++;
    }
     if(!(p->next)||j>i-1)
        return ERROR;
    q=p->next;
    p->next=q->next;
    e=q->data;
    free(q);
     rerurn OK;
}//LinkDelete_L


//建立链表
void CreatList_L(LinkList &L,int n){
    L=(LinkList)malloc(sizeof*(LNode));
    L->next=NULL;
    
    for(i=n;i>0;i--){
               p=(LinkList)malloc(sizeof*(LNode));
        scanf(&p->data);
        p->next=L->next;
        L->next=p;
    }
}//CreatList_L

//线性表的静态单链表的存储结构
#define MAXSIZE 100//链表最大长度
typedef struct{
    ElemType data;
    int cur;
}component,SLinkList[MAXSIZE];

//静态链表中的查找操作
int LocalElem_SL(LinkList S,ElemType e){
    i=S[0].cur;
    while(i&&S[i]!=e){
        i=S[i].cur;
    }
    return i;
}//LocalElem_SL


//---------栈---------


//栈的顺序存储结构
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10//当我们实现入栈操作时,发现栈满的时候可以增加最大容量,一般用realloc()语法
typedef struct {
    SElmeType *top;
    SElmeType *base;
    int stacksize;
}Sqstack;

//初始化建立一个空的栈
Status InitStack(Sqstack &S){
    S.base = (SqElmeType *)malloc(sizeof*(SqElmeType));
    if(!S.base){
             exit(OVERFLOW);
    }
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
     return OK;
}//InitStack

//获取栈顶元素
Status GetTop(Sqstack S,SqElmeType &e){
    //若栈不空则返回栈顶元素,反之则return ERROR;
    if(S.base==S.top) return ERROR;
    e=*(S.top-1);
    return OK;
}//GetTop

//插入元素
Status Push(Sqstack &S,SElmeType e){
    //首先要判断栈是否满
    if(S.top-S.base>=S.stacksize){//栈满
        S.base = (SElemType *)realloc(S.base,(S.base+SIZEINCREMENT)*sizeof(SElmeType)));
        if(!S.base) exit(OVERFLOW);
                  S.top=S.base+S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    *S.top++=e;
    return OK;
}//Push


//删除栈顶元素
Status Pop(SqStack &S,SElmeType &e){
    if(S.top==S.base) return ERROR;
    e = *(--S.top);
    return OK;
}//Pop


//------关于汉诺塔------
核心思想:
    
    假设有塔a,b,c,此时都在塔a上,先将最上面的两个分别移到两个塔,b,c上,再将最小的那一个移到那个刚分出来的大的上面,此时空出一个塔,就可以将此时原来的塔中的最上面的移到空塔上,目的就是将最下面的
移出来,重复操作,一直要想着用我前面说的方法来移开上面的,将最下面的移出来。


//单链队列---队列的链式存储结构
//先创建节点,再创建队列
typedef struct QNode {
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct {
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

//初始化队列
Status InitQueue(LinkQueue &Q)//默认存在队列Q{
    Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
    if(!Q.front) exit(OVERFLOW);
    Q.front=Q.rear=NULL;
    return OK;
}//InitQueue

//销毁链队列
Status DestroyQueue(LinkQueue &Q){
    Q.rear=Q.front->next;
    free(Q.front);
    Q.front=Q.rear;
    return OK;
}//DestroyQueue

//插入新元素
Status EnQueue(LinkQueue &Q,QElemType e){
    p=(QueuePtr)malloc(sizeof(QNode));
    p->data=e;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;
    return OK;
}//EnQueue

//删除队列头部的元素
Status DeQueue(LinkQueue &Q,QElemType &e){
    if(Q.front==Q.rear)
        return ERROR;
    p=Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)
        Q.rear=Q.front;
    free(p);
    return OK;
}//DeQueue

//---串联结----

#define MAXSTRLEN 255
#define unsigned char SString[MAXSTRLEN-1]
(S[0]用来存储串的长度)

Status Concat(SString &T,SString S1,SString S2){
    if(S1[0]+S2[0]<=MAXSTRLEN){
        for(int i=1;i<=S1[0];i++){
            T[i]=S1[i];
        }
        for(i=1;i<=S2[0];i++){
            T[S1[0]+i]=S2[i];
        }
        uncut=TURE;    
    }
    
    if(S1[0]<MAXSTRLEN){
               for(int j=1;j<=S1[0];j++){
            T[j]=S1[i];
        }
        for(j=1;j<=MAXSTRLEN-S2[0];j++){
            T[S1[0]+i]=S2[MAXSTRLEN-S2[0]];
        }
        uncut=ERROR;
    }
    if(S1[0]==MAXSTRLEN){
        for(int k=1;k<=MAXSTRLEN;k++){
            T[k]=S1[k];
        }
        uncut=ERROR;
    }
                return uncut;
}//Concat

//----求字串---
Status SString(SString &Sub,SString S,int pos,int len){
    if(pos<1||pos>StrLength(S)||len<1||len>StrLength(S)-pos+1)
        return ERROR;
    for(int i=1;i<len;i++){
        Sub[i]=S[pos+i-1];
    }
    Sub[0]=len;
    return OK;
}//SString


//---ADT String 的实现--
//串的堆分配表示
typedef struct {
       char *ch;
    int length;
}HString;
//--串的复制--
Status StrAssign(HString &T,char *chars){
    if(T.ch) {
        free(T.ch);    
    }
    //求串的长度i
    for(int i= 0,c=chars;c;++i,++c);
    if(!i){
        T.ch = NULL;
        T.length = 0;
    }else{
        if(!(T.ch=(char *)malloc(i*sizeof(char))))
            exit(OVERFLOW);
        for(int j=0;j<=i;j++){
            T.ch[j]=chars[j];
        }
                }
         return OK;    
}//StrAssign


//求串的长度
int StrLength(HString S){
    return S.length;
}//StrLength

//比较串的大小
int StrCompare(HString S,HString T) {
    for(int i=0;i<T.length&&i<S.length;i++) {
        if(S.ch[i]!=T.ch[i])
            return S.ch[i]-T.ch[i];
    }
    return S.length-T.length;
}//StrCompare

//清空串
Status ClearString(HString &S) {
    if(S.ch){
        free(S.ch);
        S.ch = NULL;
    }
    S.length= 0;
    return OK;
}//ClearString 

//拼接串
Status Concat(HString &T,HString S1,HString S2) {
    if(T.ch)
          free(T.ch);
    if(!(T.ch=(char *)malloc(S1.length+S2.length)*sizeof(char)))
        exit(OVERFLOW);
    for(int i=0;i<=S1.length-1;i++){
        T.ch[i]=S1.ch[i];
    }
    T.length=S1.length+S2.length;
    for(i=0;i<=S2.length-1;i++) {
        T.ch[S1.length+i]= S2.[i];
    }
      return OK;

}//Concat

//截取字串
Status SubString(HString &Sub,HString S,int pos ,int len) {
         if(pos<1||pos>S.length||len<0||len>S.length-pos+1)
        return ERROR;
    if(Sub.ch){
        free(Sub.ch);
    }
    //当串为空串时
    if(!len){
        Sub.ch=NULL;
        Sub.length=0;
    }else{
        if(!Sub.ch=(char *)malloc(len*sizeof(char)))
            exit(OVERFLOW);
        for(int i=0;i<=len-1;i++){
            Sub.ch[i]=S.ch[pos+i-1];
        }
    }
    return OK;

}//SubString 

//--串的块链存储
#define CHUNKSIZE 80
typedef struct Chunk{
    char ch[CHUNKSIZE];
    struct Chunk *next;
}Chunk;


typedef struct {
       Chunk *head,*tail;
    int curlen;    
}LString;

//建立二叉树

//存储结构
typedef struct BiTNode {
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
Status CreatBiTree (BiTree){
    char ch;
    scanf("%c",&ch);
    if(ch=="#")
        *T= NULL;
    else{
        *T=(BiTree)malloc(sizeof(BiTNode));
        if(!*T)
            exit(-1);
        CreatBiTree(T->lchild);
        CreatBiTree(T->rchild);//递归创建左右子树
    }
}

//先序遍历(中序以及后序与之类似,只需要调整if中的语句顺序即可)递归算法
void Pre(BiTree T){
    if(T!=NULL){
        printf("%d\t",T->data);
        Pre(T->lchild);
        Pre(T->rchild);
    }
}

//计算深度

int Depth(BiTree T) {
    if(T==NULL) return 0;
    else{
        m= Depth(T->lchild);
        n= Depth(T->rchild);
        if(m>n)
            return m+1;
        else
            return n+1;
    }
}

//节点数计算
int NodeCount(BiTree) {
    if(T==NULL)
        return 0;
    else {
        return(NodeCount(T->lchild)+NodeCount(T->rchild)+1);
    }
}

//叶子节点计算
int LeafCount(BiTree T){
    if(T==NULL)
        return 0;
    if(T->lchild== NULL&&T->rchild==NULL)
        return 1;
    else{
        return LeafCount(T->lchild)+LeafCount(T->rchild);
    }
}

//线索二叉树
//存储结构
typedef struct BiThrTree {
    int data;
    int ltag,rtag;
    struct BiThrTree *lchild,*rchild;
}BiThrTree,*BiThrTree;

//树
//每个节点的存储结构
typedef struct PTNode {
    TElemType data;
    int parent;//双亲位置域

}PTNode;

//树结构
#define MAX_TREE_SIZE 100
typedef struct {
    PTNode nodes[MAX_TREE_SIZE];
    int r,n;
}PTree;


//树结构的孩子链表形式

typedef struct CTNode {
    int child;
    struct CTNode *next;

}*ChildPtr;

typedef struct {
    TElemType data;
    ChildPtr firstchild;
}CTBox;

typedef struct {
    CTBox nodes[MAX_TREE_SIZE];
    int r,n;
}CTree;

//树的孩子兄弟表示法的存储结构

typedef struct CSNode {
    TElemType data;
    struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;

//哈夫曼树

//顺序存储结构
typedef struct {
    int weight;
    int parent,lch,rch;

}HTNode,*HuffmanTree;

//开始建树
void CreatHuffmanTree (HuffmanTree HT,int n){

//初始化数据
    if(n<=1) return ;
    m= 2*n-1;
    HT= new HTNode[m+1];//这里不算C语言的语法,可以算为伪代码,用java语法来理解
    for(i= 1;i<=m;i++) {
        HT[i].parent= 0;
        HT[i].lch= 0;
        HT[i].rch= 0;
    }
    for(i= 1;i<=n;++i) {
        cin>>HT[i].weight;
//这里也是伪代码,可与理解为输入weight的值  在c++中

    }

    for(i= n+1;i<=m;++i) {
        Select(HT,i-1,s1,s2);//这里可以用打擂台的方法来选出最小的两个值的索引 ,简而言之的封装
        HT[s1].parent= i;
        HT[s2].parent= i;
        HT[i].weight= HT[s1].weight+HT[s2].weight;
        HT[i].lch=s1;
        HT[i].rch= s2;    
    }
    
}

//图的邻接矩阵存储结构

#define MAZINT 32767
#define MVNum 100
typedef char VerTexType;
typedef int ArcType;

typedef struct {
    VerTexType vexs[MVNum];//用来输入点
    ArcType arcs[MVNum][MVNum];//网时用于存储点的权值
    int vexnum,arcnum;//总的点数和边数
    
}AMGraph;

Status CreatUDN(AMGraph &G) {
    int quanzhi;
    char v1,v2;
    scanf("%c",&G.vexnum);
    scanf("%c",&G.arcnum);
    
    for(int i=0;i<G.vexnum;i++){
        scanf("%c",&vexs[i]);
    }
    for(int i=0;i<G.vexnum;i++)
        for(int j= 0;j<G.vexnum;j++)
            arcs[i][j]=MAXINT;
    for(int i=0;i<G.vexnum;i++) {
        scanf("%d",&quanzhi);
        scanf("%c",&v1);
        scanf("%c",&v2);
        i=LocateVex(G,v1);
a        j=LocateVex(G,v2);
        arcs[i][j]= w;
        arcs[i][j]=arcs[j][i];
    }
    return OK;
}
int LocateVex(AMGraph G,VerTexType u) {
    int i;
    for(i=o;i<G.vexnum;i++) {
        if(u==G.vexs[i])
            return 1;
    }
    return -1;
}

//无向网:无方向但又权值
有向网:有方向也有权值
无向图:无方向也无权值,但是在创建是都认为权值默认为1,初始化时为0

//采用邻接矩阵的图的DFS(深度优先遍历)
void DFS(AMGraph G,int v){
//v 是你输入的起始点
//如果visit数组为0则未访问,1则已经访问
    scanf("%d",&v);
    visit[v]= true;
    for(int w= 0;w<G.vexnum;w++)
        if((G.arcs[v][w]!=0)&&(!visit[w]))
            DFS(G,w);//递归调用DFS
}

//邻接表表示方法创建无向网
Status CreatUDG(ALGraph &G) {
    scanf("%d%d",&vexnum,&arcsnum)
//输入总结数和边数
    for(int i=0;i<G.vexnum;i++) {
        scanf("%c",&G.vertice[i]);
        G.vertice[i].firstarc=NULL;
    }
    //构造邻接表
    for(int j=0;j<G.arcsnum;j++) {
        scanf("%c%c",&v1,&v2);
        i=LocalVex(G,v1);
        j=LocalVex(G,v2);
        p->adjex=j;
        p=(ANode *)malloc(sizeof(ANode));
        //尾插法
        p->next=G.vertices[i].firstarc;
        G.vertices[i].firstarc=p;
        p->adjex=j;
        //用相同操作操作另一个对称节点
        p1->next=G.vertices[j].firstarc;
        G.vertices[j].firstarc=p1;
        p1->adjex=i;
        
    }
}

  • 15
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哟西¥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值