zoukankan      html  css  js  c++  java
  • 数据结构与算法20170804

    本文介绍数据结构与算法的知识,相信很多人在学校都学习过,同时为了贴近实际,文章直接附上编译通过可直接使用的源码。

    一、数据结构

    1.线性表:

    1)带头结点的链表

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     LinkList.c
      5 * Description        :     LinkList operation center
      6 * Created            :     2017.03.02.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 typedef struct LinkList
     18 {
     19     char cData;
     20     struct LinkList *pNext;
     21 }T_LinkList,*PT_LinkList;
     22 #define LINK_LIST_LEN 10
     23 
     24 static int CreatLinkList(PT_LinkList *o_ptLinkListHead);
     25 static int LinkListInsert(T_LinkList *i_ptLinkListHead,int i_dwPosition,int i_dwElement);
     26 static int LinkListDelete(T_LinkList *i_ptLinkListHead,int i_dwPosition,int *o_dwElement);
     27 static int LinkListTraverse(T_LinkList *i_ptLinkListHead);
     28 /*****************************************************************************
     29 -Fuction        : main
     30 -Description    : main
     31 -Input            : 
     32 -Output         : 
     33 -Return         : 
     34 * Modify Date      Version         Author           Modification
     35 * -----------------------------------------------
     36 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     37 ******************************************************************************/
     38 int main(int argc,char **argv)
     39 {
     40     int dwElement=0;
     41     PT_LinkList ptLinkListHead=NULL;
     42     CreatLinkList(&ptLinkListHead);
     43     LinkListInsert(ptLinkListHead,1,1);
     44     LinkListInsert(ptLinkListHead,2,23);
     45     LinkListInsert(ptLinkListHead,3,24);
     46     LinkListInsert(ptLinkListHead,4,26);
     47     LinkListInsert(ptLinkListHead,5,66);
     48     LinkListInsert(ptLinkListHead,6,99);
     49     
     50     printf("插入结果:");
     51     LinkListTraverse(ptLinkListHead);
     52     LinkListDelete(ptLinkListHead,6,&dwElement);
     53     LinkListDelete(ptLinkListHead,4,&dwElement);
     54     
     55     printf("删除结果:");
     56     LinkListTraverse(ptLinkListHead);
     57     
     58     printf("插入结果:");
     59     LinkListInsert(ptLinkListHead,3,5);
     60     LinkListTraverse(ptLinkListHead);
     61     return 0;
     62 }
     63 /*****************************************************************************
     64 -Fuction        : CreatLinkList
     65 -Description    : CreatLinkList
     66 -Input            : 
     67 -Output         : 
     68 -Return         : 
     69 * Modify Date      Version         Author           Modification
     70 * -----------------------------------------------
     71 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     72 ******************************************************************************/
     73 static int CreatLinkList(PT_LinkList *o_ptLinkListHead)
     74 {//鐢熸垚涓€涓�ご缁撶偣
     75     int ret=-1;
     76     *o_ptLinkListHead=(T_LinkList *)malloc(sizeof(T_LinkList));// 产生头结点,并使L指向此头结点
     77     if(NULL==*o_ptLinkListHead)
     78     {
     79         printf("LinkListErr
    ");
     80         ret=-1;
     81     }
     82     else
     83     {
     84         (*o_ptLinkListHead)->pNext=NULL;
     85         ret=0;
     86     }
     87     return ret;
     88 }
     89 /*****************************************************************************
     90 -Fuction        : LinkListInsert
     91 -Description    : LinkListInsert
     92 -Input            : 
     93 -Output         : 
     94 -Return         : 
     95 * Modify Date      Version         Author           Modification
     96 * -----------------------------------------------
     97 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     98 ******************************************************************************/
     99 static int LinkListInsert(T_LinkList *i_ptLinkListHead,int i_dwPosition,int i_dwElement)
    100 {
    101     int ret=-1;
    102     T_LinkList *pLinkListNode=i_ptLinkListHead;
    103     T_LinkList *pInsertListNode=NULL;    
    104     int j=0;
    105     while((pLinkListNode!=NULL)&&(j<i_dwPosition-1))//寻找插入位置的前一个结点(计算表长(包含头结点)进行比较)
    106     {//插入位置小于等于1直接退出,没有判断pLinkListNode!=NULL
    107         pLinkListNode=pLinkListNode->pNext;//计算表长,插入位置的前一个结点包括头结点(第一个位置的时候),
    108         //所以长度包含头结点
    109         j++;//插入位置的前一个结点或者链表长度不够时表示链表长度
    110     }    
    111     if((pLinkListNode==NULL)||(j>i_dwPosition-1))
    112     {//链表长度不够为NULL,或者插入位置小于1异常,(第一个位置为1)
    113         ret=-1;        
    114         printf("InsertPositionErr,Len:%d,Pos:%d
    ",j,i_dwPosition);
    115     }
    116     else
    117     {
    118         pInsertListNode=(T_LinkList *)malloc(sizeof(T_LinkList));
    119         if(NULL==pInsertListNode)
    120         {
    121             printf("pInsertListNodeMallocErr
    ");
    122             ret=-1;
    123         }    
    124         else
    125         {
    126             pInsertListNode->pNext=NULL;
    127             pInsertListNode->cData=i_dwElement;
    128             pInsertListNode->pNext=pLinkListNode->pNext;
    129             pLinkListNode->pNext=pInsertListNode;
    130             ret=0;
    131         }
    132     }
    133     return ret;
    134 }
    135 
    136 /*****************************************************************************
    137 -Fuction        : LinkListDelete
    138 -Description    : LinkListDelete
    139 -Input            : 
    140 -Output         : 
    141 -Return         : 
    142 * Modify Date      Version         Author           Modification
    143 * -----------------------------------------------
    144 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    145 ******************************************************************************/
    146 static int LinkListDelete(T_LinkList *i_ptLinkListHead,int i_dwPosition,int *o_dwElement)
    147 {
    148     int ret=-1;
    149     T_LinkList *ptLinkListNode=i_ptLinkListHead;
    150     T_LinkList *ptDeleteListNode=NULL;
    151     int j=0;
    152     while((ptLinkListNode->pNext!=NULL)&&(j<i_dwPosition-1))//找到删除点的前驱
    153     {
    154         ptLinkListNode=ptLinkListNode->pNext;
    155         j++;
    156     }
    157     if((NULL==ptLinkListNode->pNext)||(j>i_dwPosition-1))
    158     {
    159         ret=-1;
    160         printf("LinkListDeleteErr,Len:%d,Pos:%d
    ",j,i_dwPosition);
    161     }
    162     else
    163     {
    164         ptDeleteListNode=ptLinkListNode->pNext;
    165         *o_dwElement=ptDeleteListNode->cData;
    166         ptLinkListNode->pNext=ptDeleteListNode->pNext;
    167         free(ptDeleteListNode);
    168         ret=0;
    169     }
    170     return ret;
    171 }
    172 /*****************************************************************************
    173 -Fuction        : LinkListDelete
    174 -Description    : LinkListDelete
    175 -Input            : 
    176 -Output         : 
    177 -Return         : 
    178 * Modify Date      Version         Author           Modification
    179 * -----------------------------------------------
    180 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    181 ******************************************************************************/
    182 static int LinkListTraverse(T_LinkList *i_ptLinkListHead)
    183 {
    184     int ret=-1;
    185     T_LinkList *ptLinkListNode=i_ptLinkListHead;
    186     if(ptLinkListNode->pNext==NULL)
    187     {
    188         printf("LinkListTraverseErr,LinkListEmpty
    ");
    189     }
    190     else
    191     {
    192         while(NULL!=ptLinkListNode->pNext)
    193         {
    194             ptLinkListNode=ptLinkListNode->pNext;
    195             printf("%d ",ptLinkListNode->cData);
    196         }
    197         printf("
    ");
    198         ret=0;
    199     }
    200     return ret;
    201 }
    LinkList.c

    2)带头结点表意更清晰的链表

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     LinkList.c
      5 * Description        :     LinkList operation center
      6 * Created            :     2017.03.02.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 typedef struct LinkListElement
     18 {
     19     char cData;
     20 }T_LinkListElement,*PT_LinkListElement;
     21 
     22 typedef struct LinkList
     23 {
     24     T_LinkListElement tData;
     25     struct LinkList *ptNext;
     26 }T_LinkList,*PT_LinkList;
     27 #define LINK_LIST_LEN 10
     28 
     29 static int InitLinkList(PT_LinkList *o_pptLinkListHead);
     30 static int InsertNodeToLinkList(T_LinkList *i_ptLinkListHead,int i_dwPosition,T_LinkListElement *i_ptElement);
     31 static int DeleteNodeFromLinkList(T_LinkList *i_ptLinkListHead,int i_dwPosition,T_LinkListElement *o_ptElement);
     32 static int TraverseLinkList(T_LinkList *i_ptLinkListHead);
     33 /*****************************************************************************
     34 -Fuction        : main
     35 -Description    : main
     36 -Input            : 
     37 -Output         : 
     38 -Return         : 
     39 * Modify Date      Version         Author           Modification
     40 * -----------------------------------------------
     41 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     42 ******************************************************************************/
     43 int main(int argc,char **argv)
     44 {
     45     PT_LinkList ptLinkListHead=NULL;
     46     T_LinkListElement tLinkListElement;
     47     InitLinkList(&ptLinkListHead);
     48     tLinkListElement.cData=1;
     49     InsertNodeToLinkList(ptLinkListHead,1,&tLinkListElement);
     50     tLinkListElement.cData=23;
     51     InsertNodeToLinkList(ptLinkListHead,2,&tLinkListElement);
     52     tLinkListElement.cData=24;
     53     InsertNodeToLinkList(ptLinkListHead,3,&tLinkListElement);
     54     tLinkListElement.cData=26;
     55     InsertNodeToLinkList(ptLinkListHead,4,&tLinkListElement);
     56     tLinkListElement.cData=66;
     57     InsertNodeToLinkList(ptLinkListHead,5,&tLinkListElement);
     58     tLinkListElement.cData=99;
     59     InsertNodeToLinkList(ptLinkListHead,6,&tLinkListElement);
     60     
     61     printf("插入结果:");
     62     TraverseLinkList(ptLinkListHead);
     63     DeleteNodeFromLinkList(ptLinkListHead,6,&tLinkListElement);
     64     DeleteNodeFromLinkList(ptLinkListHead,4,&tLinkListElement);
     65     
     66     printf("删除结果:");
     67     TraverseLinkList(ptLinkListHead);
     68     
     69     printf("插入结果:");
     70     tLinkListElement.cData=5;
     71     InsertNodeToLinkList(ptLinkListHead,3,&tLinkListElement);
     72     TraverseLinkList(ptLinkListHead);
     73     return 0;
     74 }
     75 /*****************************************************************************
     76 -Fuction        : InitLinkList
     77 -Description    : InitLinkList
     78 -Input            : 
     79 -Output         : 
     80 -Return         : 
     81 * Modify Date      Version         Author           Modification
     82 * -----------------------------------------------
     83 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     84 ******************************************************************************/
     85 static int InitLinkList(PT_LinkList *o_pptLinkListHead)
     86 {//鐢熸垚涓€涓�ご缁撶偣
     87     int ret=-1;
     88     *o_pptLinkListHead=(T_LinkList *)malloc(sizeof(T_LinkList));// 产生头结点,并使L指向此头结点
     89     if(NULL==*o_pptLinkListHead)
     90     {
     91         printf("LinkListErr
    ");
     92         ret=-1;
     93     }
     94     else
     95     {
     96         (*o_pptLinkListHead)->ptNext=NULL;
     97         ret=0;
     98     }
     99     return ret;
    100 }
    101 /*****************************************************************************
    102 -Fuction        : GetLinkListLength
    103 -Description    : GetLinkListLength
    104 -Input            : 
    105 -Output         : 
    106 -Return         : 
    107 * Modify Date      Version         Author           Modification
    108 * -----------------------------------------------
    109 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    110 ******************************************************************************/
    111 static int GetLinkListLength(T_LinkList *i_ptLinkListHead)
    112 {
    113     int iLength=0;
    114     T_LinkList *ptLinkListNode=NULL;
    115     if(NULL==i_ptLinkListHead)
    116     {
    117         printf("ListNull,GetLinkListLength err
    ");
    118     }
    119     else
    120     {
    121         ptLinkListNode=i_ptLinkListHead->ptNext;//头结点指向的下一个为开始放结点的地方
    122         while(NULL!=ptLinkListNode)
    123         {
    124             iLength++;
    125             ptLinkListNode=ptLinkListNode->ptNext;
    126         }
    127     }
    128     return iLength;
    129 }
    130 
    131 /*****************************************************************************
    132 -Fuction        : InsertNodeToLinkList
    133 -Description    : InsertNodeToLinkList
    134 -Input            : 
    135 -Output         : 
    136 -Return         : 
    137 * Modify Date      Version         Author           Modification
    138 * -----------------------------------------------
    139 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    140 ******************************************************************************/
    141 static int InsertNodeToLinkList(T_LinkList *i_ptLinkListHead,int i_dwPosition,T_LinkListElement *i_ptElement)
    142 {
    143     int ret=-1;
    144     T_LinkList *ptLinkListNode=i_ptLinkListHead;
    145     T_LinkList *ptInsertListNode=NULL;    
    146     int iLen=0;
    147     iLen=GetLinkListLength(i_ptLinkListHead);
    148     if(i_dwPosition<1||i_dwPosition-1>iLen)
    149     {
    150         ret=-1;        
    151         printf("InsertPositionErr,Len:%d,Pos:%d
    ",iLen,i_dwPosition);
    152     }
    153     else
    154     {
    155         while(--i_dwPosition)
    156         {
    157             ptLinkListNode=ptLinkListNode->ptNext;
    158         }
    159         ptInsertListNode=(T_LinkList *)malloc(sizeof(T_LinkList));
    160         if(NULL==ptInsertListNode)
    161         {
    162             printf("pInsertListNodeMallocErr
    ");
    163             ret=-1;
    164         }    
    165         else
    166         {
    167             ptInsertListNode->ptNext=NULL;
    168             memcpy(&ptInsertListNode->tData,i_ptElement,sizeof(T_LinkListElement));
    169             ptInsertListNode->ptNext=ptLinkListNode->ptNext;
    170             ptLinkListNode->ptNext=ptInsertListNode;
    171             ret=0;
    172         }
    173     }
    174     return ret;
    175 }
    176 
    177 /*****************************************************************************
    178 -Fuction        : DeleteNodeFromLinkList
    179 -Description    : DeleteNodeFromLinkList
    180 -Input            : 
    181 -Output         : 
    182 -Return         : 
    183 * Modify Date      Version         Author           Modification
    184 * -----------------------------------------------
    185 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    186 ******************************************************************************/
    187 static int DeleteNodeFromLinkList(T_LinkList *i_ptLinkListHead,int i_dwPosition,T_LinkListElement *o_ptElement)
    188 {
    189     int ret=-1;
    190     T_LinkList *ptLinkListNode=i_ptLinkListHead;
    191     T_LinkList *ptDeleteListNode=NULL;
    192     int iLen=0;
    193     iLen=GetLinkListLength(i_ptLinkListHead);
    194     if(i_dwPosition<1||i_dwPosition>iLen)
    195     {
    196         ret=-1;
    197         printf("LinkListDeleteErr,Len:%d,Pos:%d
    ",iLen,i_dwPosition);
    198     }
    199     else
    200     {
    201         while(--i_dwPosition)
    202         {
    203             ptLinkListNode=ptLinkListNode->ptNext;
    204         }
    205         ptDeleteListNode=ptLinkListNode->ptNext;
    206         memcpy(o_ptElement,&ptDeleteListNode->tData,sizeof(T_LinkListElement));
    207         ptLinkListNode->ptNext=ptDeleteListNode->ptNext;
    208         free(ptDeleteListNode);
    209         ret=0;
    210     }
    211     return ret;
    212 }
    213 /*****************************************************************************
    214 -Fuction        : TraverseLinkList
    215 -Description    : TraverseLinkList
    216 -Input            : 
    217 -Output         : 
    218 -Return         : 
    219 * Modify Date      Version         Author           Modification
    220 * -----------------------------------------------
    221 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    222 ******************************************************************************/
    223 static int TraverseLinkList(T_LinkList *i_ptLinkListHead)
    224 {
    225     int ret=-1;
    226     T_LinkList *ptLinkListNode=i_ptLinkListHead;
    227     if(ptLinkListNode->ptNext==NULL)
    228     {
    229         printf("LinkListTraverseErr,LinkListEmpty
    ");
    230     }
    231     else
    232     {
    233         while(NULL!=ptLinkListNode->ptNext)
    234         {
    235             ptLinkListNode=ptLinkListNode->ptNext;
    236             printf("%d ",ptLinkListNode->tData.cData);
    237         }
    238         printf("
    ");
    239         ret=0;
    240     }
    241     return ret;
    242 }
    LinkListClearOpr.c

    3)不带头结点表意更清晰的链表

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     LinkList.c
      5 * Description        :     LinkList operation center
      6 * Created            :     2017.03.02.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 #include "AdjacencyListGraph.h"
     17 
     18 /*typedef struct LinkListElement
     19 {
     20     char cData;
     21 }T_LinkListElement,*PT_LinkListElement;
     22 
     23 typedef struct LinkList
     24 {
     25     T_LinkListElement tData;
     26     struct LinkList *ptNext;
     27 }T_LinkList,*PT_LinkList;*/
     28 typedef T_ArcNode T_LinkList;
     29 
     30 #define LINK_LIST_LEN 10
     31 
     32 static int InsertNodeToLinkList(T_LinkList **i_pptLinkListHead,int i_dwPosition,T_LinkListElement *i_ptElement);
     33 static int DeleteNodeFromLinkList(T_LinkList **i_pptLinkListHead,int i_dwPosition,T_LinkListElement *o_ptElement);
     34 static int TraverseLinkList(T_LinkList *i_ptLinkListHead);
     35 static void ClearLinkList(T_LinkList *i_ptLinkListHead);
     36 
     37 #define DestroyLinkList ClearLinkList // DestroyList()和ClearList()的操作是一样的
     38 
     39 /*****************************************************************************
     40 -Fuction        : main
     41 -Description    : main
     42 -Input            : 
     43 -Output         : 
     44 -Return         : 
     45 * Modify Date      Version         Author           Modification
     46 * -----------------------------------------------
     47 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     48 ******************************************************************************/
     49 /*int main(int argc,char **argv)
     50 {
     51     PT_LinkList ptLinkListHead=NULL;
     52     T_LinkListElement tLinkListElement;
     53     tLinkListElement.cData=1;
     54     InsertNodeToLinkList(&ptLinkListHead,1,&tLinkListElement);
     55     tLinkListElement.cData=23;
     56     InsertNodeToLinkList(&ptLinkListHead,2,&tLinkListElement);
     57     tLinkListElement.cData=24;
     58     InsertNodeToLinkList(&ptLinkListHead,3,&tLinkListElement);
     59     tLinkListElement.cData=26;
     60     InsertNodeToLinkList(&ptLinkListHead,4,&tLinkListElement);
     61     tLinkListElement.cData=66;
     62     InsertNodeToLinkList(&ptLinkListHead,5,&tLinkListElement);
     63     tLinkListElement.cData=99;
     64     InsertNodeToLinkList(&ptLinkListHead,6,&tLinkListElement);
     65     
     66     printf("插入结果:");
     67     TraverseLinkList(ptLinkListHead);
     68     DeleteNodeFromLinkList(&ptLinkListHead,6,&tLinkListElement);
     69     DeleteNodeFromLinkList(&ptLinkListHead,4,&tLinkListElement);
     70     
     71     printf("删除结果:");
     72     TraverseLinkList(ptLinkListHead);
     73     
     74     printf("插入结果:");
     75     tLinkListElement.cData=5;
     76     InsertNodeToLinkList(&ptLinkListHead,3,&tLinkListElement);
     77     TraverseLinkList(ptLinkListHead);
     78     return 0;
     79 }*/
     80 /*****************************************************************************
     81 -Fuction        : GetLinkListLength
     82 -Description    : GetLinkListLength
     83 -Input            : 
     84 -Output         : 
     85 -Return         : 
     86 * Modify Date      Version         Author           Modification
     87 * -----------------------------------------------
     88 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     89 ******************************************************************************/
     90 static int GetLinkListLength(T_LinkList *i_ptLinkListHead)
     91 {
     92     int iLength=0;
     93     T_LinkList *ptLinkListNode=i_ptLinkListHead;
     94     if(NULL==ptLinkListNode)
     95     {
     96         //printf("ListNull
    ");
     97     }
     98     else
     99     {
    100         while(NULL!=ptLinkListNode)
    101         {
    102             iLength++;
    103             ptLinkListNode=ptLinkListNode->ptNext;
    104         }
    105     }
    106     return iLength;
    107 }
    108 
    109 /*****************************************************************************
    110 -Fuction        : InsertNodeToLinkList
    111 -Description    : InsertNodeToLinkList
    112 -Input            : 
    113 -Output         : 
    114 -Return         : 
    115 * Modify Date      Version         Author           Modification
    116 * -----------------------------------------------
    117 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    118 ******************************************************************************/
    119 static int InsertNodeToLinkList(T_LinkList **i_pptLinkListHead,int i_dwPosition,T_LinkListElement *i_ptElement)
    120 {
    121     int ret=-1;
    122     T_LinkList *ptLinkListNode=*i_pptLinkListHead;
    123     T_LinkList *ptInsertListNode=NULL;    
    124     int iLen=0;
    125     int iPreInsertPos=0;
    126     iLen=GetLinkListLength(ptLinkListNode);
    127     if(i_dwPosition<1||i_dwPosition-1>iLen)
    128     {// i值不合法// i大于表长+1
    129         ret=-1;        
    130         printf("InsertPositionErr,Len:%d,Pos:%d
    ",iLen,i_dwPosition);
    131     }
    132     else
    133     {
    134         ptInsertListNode=(T_LinkList *)malloc(sizeof(T_LinkList));
    135         if(NULL==ptInsertListNode)
    136         {
    137             printf("pInsertListNodeMallocErr
    ");
    138             ret=-1;
    139         }    
    140         else
    141         {
    142             ptInsertListNode->ptNext=NULL;
    143             memcpy(&ptInsertListNode->tData,i_ptElement,sizeof(T_LinkListElement));
    144             if(1==i_dwPosition)// 插在表头
    145             {
    146                 ptInsertListNode->ptNext=*i_pptLinkListHead;
    147                 *i_pptLinkListHead=ptInsertListNode;// 改变L
    148             }
    149             else
    150             {
    151                 iPreInsertPos=i_dwPosition-1;
    152                 while(--iPreInsertPos)// 寻找第i-1个结点插入点的前一个位置
    153                 {//不能直接用插入点的位置,因为插入点前一个位置的next指针也要修改
    154                     ptLinkListNode=ptLinkListNode->ptNext;//前一个结点的next指针修改后才能连接起来
    155                 }
    156                 ptInsertListNode->ptNext=ptLinkListNode->ptNext;//原先结点放到现在后面
    157                 ptLinkListNode->ptNext=ptInsertListNode;//与前一个结点连接
    158             }
    159             ret=0;
    160         }
    161     }
    162     return ret;
    163 }
    164 
    165 /*****************************************************************************
    166 -Fuction        : DeleteNodeFromLinkList
    167 -Description    : DeleteNodeFromLinkList
    168 -Input            : 
    169 -Output         : 
    170 -Return         : 
    171 * Modify Date      Version         Author           Modification
    172 * -----------------------------------------------
    173 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    174 ******************************************************************************/
    175 static int DeleteNodeFromLinkList(T_LinkList **i_pptLinkListHead,int i_dwPosition,T_LinkListElement *o_ptElement)
    176 {
    177     int ret=-1;
    178     T_LinkList *ptLinkListNode=*i_pptLinkListHead;
    179     T_LinkList *ptDeleteListNode=NULL;
    180     int iLen=0;
    181     int iPreDeletePos=0;
    182     iLen=GetLinkListLength(ptLinkListNode);
    183     if(i_dwPosition<1||i_dwPosition>iLen||(0==iLen))
    184     {// i值不合法// i大于表长//空表
    185         ret=-1;
    186         printf("LinkListDeleteErr,Len:%d,Pos:%d
    ",iLen,i_dwPosition);
    187     }
    188     else
    189     {
    190         if(1==i_dwPosition)
    191         {
    192             memcpy(o_ptElement,&ptLinkListNode->tData,sizeof(T_LinkListElement));
    193             *i_pptLinkListHead=ptLinkListNode->ptNext;// L由第2个结点开始
    194             free(ptLinkListNode);// 删除并释放第1个结点
    195         }
    196         else
    197         {
    198             iPreDeletePos=i_dwPosition-1;
    199             while(--iPreDeletePos)//寻找第i-1个结点
    200             {
    201                 ptLinkListNode=ptLinkListNode->ptNext;
    202             }
    203             ptDeleteListNode=ptLinkListNode->ptNext;// 删除并释放结点
    204             memcpy(o_ptElement,&ptDeleteListNode->tData,sizeof(T_LinkListElement));
    205             ptLinkListNode->ptNext=ptDeleteListNode->ptNext;
    206             free(ptDeleteListNode);
    207         }
    208         ret=0;
    209     }
    210     return ret;
    211 }
    212 /*****************************************************************************
    213 -Fuction        : TraverseLinkList
    214 -Description    : TraverseLinkList
    215 -Input            : 
    216 -Output         : 
    217 -Return         : 
    218 * Modify Date      Version         Author           Modification
    219 * -----------------------------------------------
    220 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    221 ******************************************************************************/
    222 static int TraverseLinkList(T_LinkList *i_ptLinkListHead)
    223 {
    224     int ret=-1;
    225     T_LinkList *ptLinkListNode=i_ptLinkListHead;
    226     if(ptLinkListNode==NULL)
    227     {
    228         printf("LinkListTraverseErr,LinkListEmpty
    ");
    229     }
    230     else
    231     {
    232         while(NULL!=ptLinkListNode)
    233         {
    234             //printf("%d ",ptLinkListNode->tData.cData);
    235             ptLinkListNode=ptLinkListNode->ptNext;
    236         }
    237         printf("
    ");
    238         ret=0;
    239     }
    240     return ret;
    241 }
    242 
    243 /*****************************************************************************
    244 -Fuction        : ClearLinkList
    245 -Description    : ClearLinkList
    246 -Input            : 
    247 -Output         : 
    248 -Return         : 
    249 * Modify Date      Version         Author           Modification
    250 * -----------------------------------------------
    251 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    252 ******************************************************************************/
    253 static void ClearLinkList(T_LinkList *i_ptLinkListHead)
    254 { // 初始条件:线性表L已存在。操作结果:将L重置为空表(见图213)
    255     T_LinkList *ptLinkListNode;
    256     while(i_ptLinkListHead) // L不空
    257     {
    258         ptLinkListNode=i_ptLinkListHead; // p指向首元结点
    259         i_ptLinkListHead=i_ptLinkListHead->ptNext; // L指向第2个结点(新首元结点)
    260         free(ptLinkListNode); // 释放首元结点
    261     }
    262 }
    263 
    264 /*****************************************************************************
    265 -Fuction        : GetLinkListNodeLocation
    266 -Description    : GetLinkListNodeLocation
    267 -Input            : 
    268 -Output         : 
    269 -Return         : 
    270 * Modify Date      Version         Author           Modification
    271 * -----------------------------------------------
    272 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    273 ******************************************************************************/
    274 static int GetLinkListNodeLocation(T_LinkList *i_ptLinkListHead,T_LinkListElement *i_ptElement,int (*Compare)(T_LinkListElement *i_ptElement1,T_LinkListElement *i_ptElement2))
    275 {
    276     int iLocation=0;
    277     T_LinkList *ptLinkListNode=i_ptLinkListHead;
    278     while(NULL!=ptLinkListNode)
    279     {
    280         iLocation++;
    281         if(0==Compare(&ptLinkListNode->tData,i_ptElement))
    282         {
    283             break;
    284         }
    285         else
    286         {
    287             ptLinkListNode=ptLinkListNode->ptNext;
    288         }
    289     }
    290     if(NULL==ptLinkListNode)
    291     {
    292         iLocation=0;//没找到返回0
    293     }
    294     else
    295     {
    296     }
    297     return iLocation;
    298 }
    299 
    300 /*****************************************************************************
    301 -Fuction        : GetLinkListNodePoint
    302 -Description    : GetLinkListNodePoint
    303 -Input            : 
    304 -Output         : 
    305 -Return         : 
    306 * Modify Date      Version         Author           Modification
    307 * -----------------------------------------------
    308 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    309 ******************************************************************************/
    310 static T_LinkList *GetLinkListNodePoint(T_LinkList *i_ptLinkListHead,T_LinkListElement *i_ptElement,int (*Compare)(T_LinkListElement *i_ptElement1,T_LinkListElement *i_ptElement2),T_LinkList **o_pptElementPreNode)
    311 {
    312     int i,j;
    313     T_LinkList *ptLinkListNode=NULL;
    314     i=GetLinkListNodeLocation(i_ptLinkListHead,i_ptElement,Compare);
    315     if(0==i)
    316     {
    317     }
    318     else
    319     {
    320         if(1==i)
    321         {
    322             ptLinkListNode=i_ptLinkListHead;
    323             *o_pptElementPreNode=NULL;//前驱为null
    324         }
    325         else
    326         {
    327             ptLinkListNode=i_ptLinkListHead;    
    328             for(j=2;j<i;j++)
    329             {
    330                 ptLinkListNode=ptLinkListNode->ptNext;
    331             }
    332             *o_pptElementPreNode=ptLinkListNode;
    333             ptLinkListNode=ptLinkListNode->ptNext;
    334         }
    335     }
    336     return ptLinkListNode;
    337 }
    338 
    339 /*****************************************************************************
    340 -Fuction        : DeleteElementFromLinkList
    341 -Description    : DeleteElementFromLinkList
    342 -Input            : 
    343 -Output         : 
    344 -Return         : 
    345 * Modify Date      Version         Author           Modification
    346 * -----------------------------------------------
    347 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    348 ******************************************************************************/
    349 static int DeleteElementFromLinkList(T_LinkList *i_ptLinkListHead,T_LinkListElement *m_ptElement,int (*Compare)(T_LinkListElement *i_ptElement1,T_LinkListElement *i_ptElement2))
    350 {
    351     int iRet=-1;
    352     T_LinkList *ptLinkListNode=NULL;
    353     T_LinkList *ptLinkListPreNode=NULL;
    354     
    355     ptLinkListNode=GetLinkListNodePoint(i_ptLinkListHead,m_ptElement,Compare,&ptLinkListPreNode);
    356     if(NULL==ptLinkListNode)
    357     {
    358         iRet=-1;
    359     }
    360     else// 找到此结点
    361     {
    362         if(NULL==ptLinkListPreNode)// 该结点是首元结点
    363         {
    364             DeleteNodeFromLinkList(&i_ptLinkListHead,1,m_ptElement);
    365         }
    366         else// 该结点不是首元结点,ptLinkListPreNode指向其前驱
    367         {
    368             DeleteNodeFromLinkList(&ptLinkListPreNode,2,m_ptElement);
    369         }
    370         iRet=0;
    371     }
    372     return iRet;
    373 }
    LinkListClearOprNoHeadNode.c

    4)双向链表

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     DualLinkList.c
      5 * Description        :     DualLinkList operation center
      6 * Created            :     2017.04.02.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 typedef struct DualLinkList
     18 {
     19     char cData;    
     20     struct DualLinkList *ptPrior;
     21     struct DualLinkList *ptNext;
     22 }T_DualLinkList,*PT_DualLinkList;
     23 
     24 static int ListLength(T_DualLinkList *i_ptDualLinkListHead);
     25 static int GetElementPoint(T_DualLinkList *i_ptDualLinkListHead,int i_dwPosition,T_DualLinkList **o_pptElementPoint);
     26 static int ListInit(T_DualLinkList **i_pptDualLinkListHead);
     27 static int ListInsert(T_DualLinkList *i_ptDualLinkListHead,int i_dwPosition,int i_dwElement);
     28 static int ListDelete(T_DualLinkList *i_ptDualLinkListHead,int i_dwPosition,int *o_dwElement);
     29 static int ListTraverse(T_DualLinkList *i_ptDualLinkListHead);
     30 static int ListSortOneCmpOne(T_DualLinkList *i_ptDualLinkListHead);
     31 static int ListSortOneCmpAll(T_DualLinkList *i_ptDualLinkListHead);
     32 
     33 /*****************************************************************************
     34 -Fuction        : main
     35 -Description    : main
     36 -Input            : 
     37 -Output         : 
     38 -Return         : 
     39 * Modify Date      Version         Author           Modification
     40 * -----------------------------------------------
     41 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     42 ******************************************************************************/
     43 int main(int argc,char **argv)
     44 {
     45     int dwElement=0;
     46     T_DualLinkList *ptLinkListHead=NULL;
     47     ListInit(&ptLinkListHead);
     48     ListInsert(ptLinkListHead,1,1);
     49     ListInsert(ptLinkListHead,2,99);
     50     ListInsert(ptLinkListHead,3,24);
     51     ListInsert(ptLinkListHead,4,26);
     52     ListInsert(ptLinkListHead,5,8);
     53     ListInsert(ptLinkListHead,6,33);
     54     printf("插入结果:");
     55     ListTraverse(ptLinkListHead);
     56     
     57     ListSortOneCmpOne(ptLinkListHead);
     58     printf("两两比较冒泡排序结果:");
     59     ListTraverse(ptLinkListHead);
     60     
     61     ListDelete(ptLinkListHead,4,&dwElement);    
     62     printf("删除结果:");
     63     ListTraverse(ptLinkListHead);
     64     
     65     printf("插入结果:");
     66     ListInsert(ptLinkListHead,3,5);
     67     ListTraverse(ptLinkListHead);
     68     
     69     ListSortOneCmpAll(ptLinkListHead);
     70     printf("一对多比较冒泡排序结果:");
     71     ListTraverse(ptLinkListHead);
     72     
     73     return 0;
     74 }
     75 /*****************************************************************************
     76 -Fuction        : ListInit
     77 -Description    : ListInit
     78 -Input            : 
     79 -Output         : 
     80 -Return         : 
     81 * Modify Date      Version         Author           Modification
     82 * -----------------------------------------------
     83 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     84 ******************************************************************************/
     85 static int ListInit(T_DualLinkList **i_pptDualLinkListHead)
     86 {
     87     int iRet=0;
     88     T_DualLinkList *ptListNode=NULL; 
     89     ptListNode=(T_DualLinkList *)malloc(sizeof(T_DualLinkList));
     90     if(NULL==ptListNode)
     91     {
     92         iRet=-1;
     93         printf("ListInitMallocErr,ListInitFail!
    ");
     94         exit(-1);
     95     }
     96     else
     97     {
     98         ptListNode->ptNext=ptListNode->ptPrior=ptListNode;
     99         *i_pptDualLinkListHead=ptListNode;
    100         iRet=0;
    101     }
    102     return iRet;
    103 }
    104 /*****************************************************************************
    105 -Fuction        : ListInit
    106 -Description    : ListInit
    107 -Input            : 
    108 -Output         : 
    109 -Return         : 
    110 * Modify Date      Version         Author           Modification
    111 * -----------------------------------------------
    112 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    113 ******************************************************************************/
    114 static int ListInsert(T_DualLinkList *i_ptDualLinkListHead,int i_dwPosition,int i_dwElement)
    115 {
    116     int iRet=0;
    117     T_DualLinkList *ptListNode=i_ptDualLinkListHead; 
    118     T_DualLinkList *ptListInsertNode=NULL;
    119     if((i_dwPosition<1)||(i_dwPosition>ListLength(i_ptDualLinkListHead)+1))
    120     {
    121         printf("ListInserErr
    ");
    122         iRet=-1;
    123     }
    124     else
    125     {
    126         if(0!=GetElementPoint(i_ptDualLinkListHead,i_dwPosition-1,&ptListNode))//找插入点的前驱
    127         {//或者找插入点位置也是可以的
    128             printf("ListInsertGetElementPoint Err
    ");
    129             iRet=-1;
    130         }
    131         else
    132         {
    133             ptListInsertNode=(T_DualLinkList *)malloc(sizeof(T_DualLinkList));
    134             if(NULL==ptListInsertNode)
    135             {
    136                 iRet=-1;
    137                 printf("ListInsertMallocErr
    ");
    138             }
    139             else
    140             {
    141                 ptListInsertNode->cData=i_dwElement;
    142                 ptListInsertNode->ptNext=ptListNode->ptNext;
    143                 ptListInsertNode->ptPrior=ptListNode;
    144                 ptListNode->ptNext->ptPrior=ptListInsertNode;
    145                 ptListNode->ptNext=ptListInsertNode;
    146                 iRet=0;
    147             }
    148         }
    149     }
    150     return iRet;
    151 }
    152 /*****************************************************************************
    153 -Fuction        : ListInit
    154 -Description    : ListInit
    155 -Input            : 
    156 -Output         : 
    157 -Return         : 
    158 * Modify Date      Version         Author           Modification
    159 * -----------------------------------------------
    160 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    161 ******************************************************************************/
    162 static int ListDelete(T_DualLinkList *i_ptDualLinkListHead,int i_dwPosition,int *o_dwElement)
    163 {
    164     int iRet=0;
    165     T_DualLinkList *ptListNode=NULL; 
    166     if((i_dwPosition<1)||(i_dwPosition>ListLength(i_ptDualLinkListHead)))
    167     {
    168         printf("ListDelete Err
    ");
    169         iRet=-1;
    170     }
    171     else
    172     {
    173         if(0!=GetElementPoint(i_ptDualLinkListHead,i_dwPosition,&ptListNode))//找删除点位置
    174         {
    175             printf("ListDeleteGetElementPoint Err
    ");
    176             iRet=-1;
    177         }
    178         else
    179         {
    180             *o_dwElement=ptListNode->cData;
    181             ptListNode->ptPrior->ptNext=ptListNode->ptNext;
    182             ptListNode->ptNext->ptPrior=ptListNode->ptPrior;
    183             free(ptListNode);
    184             iRet=0;
    185         }
    186     }
    187     return iRet;
    188 }
    189 /*****************************************************************************
    190 -Fuction        : ListInit
    191 -Description    : ListInit
    192 -Input            : 
    193 -Output         : 
    194 -Return         : 
    195 * Modify Date      Version         Author           Modification
    196 * -----------------------------------------------
    197 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    198 ******************************************************************************/
    199 static int ListTraverse(T_DualLinkList *i_ptDualLinkListHead)
    200 {
    201     int iRet=0;
    202     T_DualLinkList *ptListNode=NULL; 
    203     if(NULL==i_ptDualLinkListHead)
    204     {
    205         iRet=-1;
    206         printf("ListTraverse Err,HeadNull
    ");
    207     }
    208     else
    209     {
    210         ptListNode=i_ptDualLinkListHead->ptNext;
    211         while(i_ptDualLinkListHead!=ptListNode)
    212         {
    213             printf("%d ",ptListNode->cData);
    214             ptListNode=ptListNode->ptNext;
    215         }
    216         printf("
    ");
    217         iRet=0;
    218     }
    219     return iRet;
    220 }
    221 /*****************************************************************************
    222 -Fuction        : ListInit
    223 -Description    : ListInit
    224 -Input            : 
    225 -Output         : 
    226 -Return         : 
    227 * Modify Date      Version         Author           Modification
    228 * -----------------------------------------------
    229 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    230 ******************************************************************************/
    231 static int ListSortOneCmpOne(T_DualLinkList *i_ptDualLinkListHead)
    232 {
    233     int iRet=0;
    234     char cData;
    235     int i=0,j=0;
    236     T_DualLinkList *ptListSortNode=NULL;
    237     if(NULL==i_ptDualLinkListHead)
    238     {
    239         iRet=-1;
    240         printf("ListSortOneCmpOne Err,HeadNull
    ");
    241     }
    242     else
    243     {
    244         for(i=0;i<ListLength(i_ptDualLinkListHead)-1;i++)//总趟数
    245         {
    246             ptListSortNode=i_ptDualLinkListHead->ptNext;//最大的在后面所以最后一个不需要比较
    247             for(j=0;j<ListLength(i_ptDualLinkListHead)-i-1;j++)//但是第一个也就是前面还要比较
    248             {
    249                 if(ptListSortNode->cData>ptListSortNode->ptNext->cData)//两两比较找出最大的放最后面
    250                 {//大的放后面
    251                     cData=ptListSortNode->cData;
    252                     ptListSortNode->cData=ptListSortNode->ptNext->cData;
    253                     ptListSortNode->ptNext->cData=cData;
    254                 }
    255                 ptListSortNode=ptListSortNode->ptNext;
    256             }
    257         }
    258         iRet=0;
    259     }
    260     return iRet;
    261 }
    262 /*****************************************************************************
    263 -Fuction        : ListInit
    264 -Description    : ListInit
    265 -Input            : 
    266 -Output         : 
    267 -Return         : 
    268 * Modify Date      Version         Author           Modification
    269 * -----------------------------------------------
    270 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    271 ******************************************************************************/
    272 static int ListSortOneCmpAll(T_DualLinkList *i_ptDualLinkListHead)
    273 {
    274     int iRet=0;
    275     char cData;
    276     int i=0,j=0;
    277     T_DualLinkList *ptListNode=i_ptDualLinkListHead; 
    278     T_DualLinkList *ptListSortNode=NULL;
    279     if(NULL==i_ptDualLinkListHead)
    280     {
    281         iRet=-1;
    282         printf("ListSortOneCmpAll Err,HeadNull
    ");
    283     }
    284     else
    285     {
    286         for(i=0;i<ListLength(i_ptDualLinkListHead)-1;i++)//总趟数
    287         {
    288             ptListSortNode=ptListNode=ptListNode->ptNext;
    289             for(j=0;j<ListLength(i_ptDualLinkListHead)-i-1;j++)//一趟比较次数
    290             {
    291                 if(ptListNode->cData>ptListSortNode->ptNext->cData)//一比较多找出最小的放最前面
    292                 {//小的放前面
    293                     cData=ptListNode->cData;
    294                     ptListNode->cData=ptListSortNode->ptNext->cData;
    295                     ptListSortNode->ptNext->cData=cData;
    296                 }
    297                 ptListSortNode=ptListSortNode->ptNext;
    298             }
    299         }
    300         iRet=0;
    301     }
    302     return iRet;
    303 }
    304 
    305 /*****************************************************************************
    306 -Fuction        : GetElementPoint
    307 -Description    : GetElementPoint
    308 -Input            : 
    309 -Output         : 
    310 -Return         : 
    311 * Modify Date      Version         Author           Modification
    312 * -----------------------------------------------
    313 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    314 ******************************************************************************/
    315 static int GetElementPoint(T_DualLinkList *i_ptDualLinkListHead,int i_dwPosition,T_DualLinkList **o_pptElementPoint)
    316 {
    317     int iRet=0;    
    318     int j=0;
    319     T_DualLinkList *ptDualLinkListNode=i_ptDualLinkListHead;
    320     if((i_dwPosition<0)||(i_dwPosition>ListLength(i_ptDualLinkListHead)))
    321     {
    322         iRet=-1;
    323         printf("GetElementPoint Err
    ");
    324     }
    325     else
    326     {
    327         for(j=0;j<i_dwPosition;j++)
    328         {
    329             ptDualLinkListNode=ptDualLinkListNode->ptNext;
    330         }
    331         *o_pptElementPoint=ptDualLinkListNode;
    332         iRet=0;
    333     }
    334     return iRet;
    335 }
    336 
    337 /*****************************************************************************
    338 -Fuction        : ListLength
    339 -Description    : 双向链表是循环链表遍历长度需要比对的是头
    340 结点
    341 -Input            : 
    342 -Output         : 
    343 -Return         : 
    344 * Modify Date      Version         Author           Modification
    345 * -----------------------------------------------
    346 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    347 ******************************************************************************/
    348 static int ListLength(T_DualLinkList *i_ptDualLinkListHead)
    349 {
    350     int iLength=0;
    351     T_DualLinkList *ptDualLinkListNode=i_ptDualLinkListHead->ptNext;
    352     while(i_ptDualLinkListHead!=ptDualLinkListNode)//双向循环链表区别
    353     {
    354         iLength++;
    355         ptDualLinkListNode=ptDualLinkListNode->ptNext;
    356     }
    357     return iLength;
    358 }
    DualLinkList.c

    5)顺序表

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     SequenceList.c
      5 * Description        :     SequenceList operation center
      6 * Created            :     2017.05.22.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 typedef struct SeqListElement//顺序表结点里只有数据元素
     18 {
     19     char cData;
     20 }T_SeqListElement,*PT_SeqListElement;//结点等同于数据元素
     21 
     22 typedef struct SeqList
     23 {
     24     T_SeqListElement *ptBase;//所以为了方便,直接表元素代替表结点
     25     int iCurLength;
     26     int iMaxLength;
     27 }T_SeqList,*PT_SeqList;
     28 
     29 #define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量
     30 #define LIST_INCREMENT 2 // 线性表存储空间的分配增量
     31 
     32 
     33 static int InitSeqList(T_SeqList *m_ptSeqList);
     34 static int IsSeqListEmpty(T_SeqList *i_ptSeqList);
     35 static int InsertElementToSeqList(T_SeqList *i_ptSeqList,int i_dwInsertPos,T_SeqListElement *i_ptInsertElement);
     36 static int DeleteElementFromSeqList(T_SeqList *i_ptSeqList,int i_dwInsertPos,T_SeqListElement *o_ptDeleteElement);
     37 static int TraverseSequenceList(T_SeqList *i_ptSeqList);
     38 /*****************************************************************************
     39 -Fuction        : main
     40 -Description    : main
     41 -Input            : 
     42 -Output         : 
     43 -Return         : 
     44 * Modify Date      Version         Author           Modification
     45 * -----------------------------------------------
     46 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     47 ******************************************************************************/
     48 int main(int argc,char **argv)
     49 {
     50     T_SeqListElement tElement={0};
     51     T_SeqList tSeqList={0};
     52     InitSeqList(&tSeqList);
     53     tElement.cData=1;
     54     InsertElementToSeqList(&tSeqList,1,&tElement);
     55     tElement.cData=23;
     56     InsertElementToSeqList(&tSeqList,2,&tElement);
     57     tElement.cData=24;
     58     InsertElementToSeqList(&tSeqList,3,&tElement);
     59     tElement.cData=26;
     60     InsertElementToSeqList(&tSeqList,4,&tElement);
     61     tElement.cData=66;
     62     InsertElementToSeqList(&tSeqList,5,&tElement);
     63     tElement.cData=99;
     64     InsertElementToSeqList(&tSeqList,6,&tElement);
     65     printf("插入结果:");
     66     TraverseSequenceList(&tSeqList);
     67     
     68     DeleteElementFromSeqList(&tSeqList,6,&tElement);
     69     DeleteElementFromSeqList(&tSeqList,4,&tElement);
     70     printf("删除结果:");
     71     TraverseSequenceList(&tSeqList);
     72     
     73     printf("插入结果:");
     74     tElement.cData=5;
     75     InsertElementToSeqList(&tSeqList,3,&tElement);
     76     TraverseSequenceList(&tSeqList);
     77     return 0;
     78 }
     79 
     80 
     81 /*****************************************************************************
     82 -Fuction        : InitSeqList
     83 -Description    : InitSeqList
     84 -Input            : 
     85 -Output         : 
     86 -Return         : 
     87 * Modify Date      Version         Author           Modification
     88 * -----------------------------------------------
     89 * 2017/03/29      V1.0.0         Yu Weifeng       Created
     90 ******************************************************************************/
     91 static int InitSeqList(T_SeqList *m_ptSeqList)
     92 {
     93     int ret=-1;
     94     m_ptSeqList->ptBase=(T_SeqListElement *)malloc(sizeof(T_SeqListElement)*LIST_INIT_SIZE);
     95     if(NULL==m_ptSeqList->ptBase)
     96     {
     97         printf("InitSeqList Err
    ");
     98         ret=-1;
     99     }
    100     else
    101     {
    102         m_ptSeqList->iCurLength=0;
    103         m_ptSeqList->iMaxLength=LIST_INIT_SIZE;
    104         ret=0;
    105     }
    106     return ret;
    107 }
    108 
    109 /*****************************************************************************
    110 -Fuction        : IsSeqListEmpty
    111 -Description    : IsSeqListEmpty
    112 -Input            : 
    113 -Output         : 
    114 -Return         : 
    115 * Modify Date      Version         Author           Modification
    116 * -----------------------------------------------
    117 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    118 ******************************************************************************/
    119 static int IsSeqListEmpty(T_SeqList *i_ptSeqList)
    120 {
    121     int ret=-1;
    122     if(0==i_ptSeqList->iCurLength)
    123     {
    124         ret=0;
    125     }
    126     else
    127     {
    128         ret=-1;
    129     }
    130     return ret;
    131 }
    132 
    133 /*****************************************************************************
    134 -Fuction        : InsertSeqList
    135 -Description    : InsertSeqList
    136 -Input            : i_dwInsertPos 从1 开始算的
    137 -Output         : 
    138 -Return         : 
    139 * Modify Date      Version         Author           Modification
    140 * -----------------------------------------------
    141 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    142 ******************************************************************************/
    143 static int InsertElementToSeqList(T_SeqList *i_ptSeqList,int i_dwInsertPos,T_SeqListElement *i_ptInsertElement)
    144 {
    145     int ret=-1;
    146     T_SeqListElement *ptNewBase=NULL;
    147     T_SeqListElement *ptInsertElement=NULL;
    148     T_SeqListElement *ptSeqListElement=NULL;
    149     if(i_dwInsertPos<1||i_dwInsertPos>i_ptSeqList->iCurLength+1)// i_dwInsertPos值不合法
    150     {
    151         ret=-1;
    152     }
    153     else
    154     {
    155         if(i_ptSeqList->iCurLength>=i_ptSeqList->iMaxLength)// 当前存储空间已满,增加分配
    156         {
    157             ptNewBase=(T_SeqListElement *)realloc(i_ptSeqList->ptBase,(i_ptSeqList->iMaxLength+LIST_INCREMENT)*sizeof(T_SeqListElement));
    158             if(NULL==ptNewBase)
    159             {
    160                 printf("InsertSeqList realloc err
    ");
    161                 ret=-1;
    162                 exit(-1);
    163             }
    164             else
    165             {
    166                 i_ptSeqList->ptBase=ptNewBase;
    167                 i_ptSeqList->iMaxLength+=LIST_INCREMENT;
    168             }
    169         }
    170         else
    171         {
    172         }
    173         ptInsertElement=i_ptSeqList->ptBase+i_dwInsertPos-1;//从0开始算等价于i_ptSeqList->ptBase[i_dwInsertPos-1]
    174         for(ptSeqListElement=i_ptSeqList->ptBase+i_ptSeqList->iCurLength-1;ptSeqListElement>=ptInsertElement;ptSeqListElement--)
    175         {// 插入位置及之后的元素右移
    176             memcpy(ptSeqListElement+1,ptSeqListElement,sizeof(T_SeqListElement));
    177         }
    178         memcpy(ptInsertElement,i_ptInsertElement,sizeof(T_SeqListElement));
    179         i_ptSeqList->iCurLength++;
    180         ret=0;
    181     }
    182     return ret;
    183 }
    184 
    185 /*****************************************************************************
    186 -Fuction        : DeleteElementFromSeqList
    187 -Description    : DeleteElementFromSeqList
    188 -Input            : i_dwInsertPos 从1 开始算的
    189 -Output         : 
    190 -Return         : 
    191 * Modify Date      Version         Author           Modification
    192 * -----------------------------------------------
    193 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    194 ******************************************************************************/
    195 static int DeleteElementFromSeqList(T_SeqList *i_ptSeqList,int i_dwInsertPos,T_SeqListElement *o_ptDeleteElement)
    196 {
    197     int ret=-1;
    198     T_SeqListElement *ptNewBase=NULL;
    199     T_SeqListElement *ptDeleteElement=NULL;
    200     T_SeqListElement *ptSeqListElement=NULL;
    201     if(i_dwInsertPos<1||i_dwInsertPos>i_ptSeqList->iCurLength)// i_dwInsertPos值不合法
    202     {
    203         ret=-1;
    204     }
    205     else
    206     {
    207         ptDeleteElement=i_ptSeqList->ptBase+i_dwInsertPos-1;//从0开始算等价于i_ptSeqList->ptBase[i_dwInsertPos-1]
    208         memcpy(o_ptDeleteElement,ptDeleteElement,sizeof(T_SeqListElement));
    209         for(ptSeqListElement=ptDeleteElement+1;ptSeqListElement<=i_ptSeqList->ptBase+i_ptSeqList->iCurLength-1;ptSeqListElement++)
    210         {// 被删除元素之后的元素左移
    211             memcpy(ptSeqListElement-1,ptSeqListElement,sizeof(T_SeqListElement));
    212         }
    213         i_ptSeqList->iCurLength--;
    214         ret=0;
    215     }
    216     return ret;
    217 }
    218 
    219 /*****************************************************************************
    220 -Fuction        : TraverseSequenceList
    221 -Description    : TraverseSequenceList
    222 -Input            : 
    223 -Output         : 
    224 -Return         : 
    225 * Modify Date      Version         Author           Modification
    226 * -----------------------------------------------
    227 * 2017/03/29      V1.0.0         Yu Weifeng       Created
    228 ******************************************************************************/
    229 static int TraverseSequenceList(T_SeqList *i_ptSeqList)
    230 {
    231     int ret=-1;
    232     int i;
    233     for(i=0;i<i_ptSeqList->iCurLength;i++)
    234     {
    235         printf("%d ",i_ptSeqList->ptBase[i].cData);
    236     }
    237     printf("
    ");
    238     return ret;
    239 }
    SequenceList.c

    2.队列:

    1)链式队列

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     LinkQueue.c
      5 * Description        :     LinkQueue operation center
      6 * Created            :     2017.04.24.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 #include "LinkQueue.h"
     17 
     18 static void TraverseLinkQueue(T_LinkQueue *i_ptLinkQueue);
     19 
     20 /*****************************************************************************
     21 -Fuction        : main
     22 -Description    : main
     23 -Input            : 
     24 -Output         : 
     25 -Return         : 
     26 * Modify Date      Version         Author           Modification
     27 * -----------------------------------------------
     28 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     29 ******************************************************************************/
     30 /*int main(int argc,char **argv)
     31 {
     32     T_LinkQueue tLinkQueue={0};
     33     char cElementData=0;
     34     InitLinkQueue(&tLinkQueue);
     35     
     36     EnterLinkQueue(&tLinkQueue,1);
     37     EnterLinkQueue(&tLinkQueue,2);
     38     EnterLinkQueue(&tLinkQueue,3);
     39     EnterLinkQueue(&tLinkQueue,4);
     40     EnterLinkQueue(&tLinkQueue,5);
     41     printf("进入队列结果:");
     42     TraverseLinkQueue(&tLinkQueue);
     43     
     44     ExitLinkQueue(&tLinkQueue,&cElementData);
     45     printf("退出队列元素:%d
    ",cElementData);
     46     ExitLinkQueue(&tLinkQueue,&cElementData);
     47     printf("退出队列元素:%d
    ",cElementData);
     48     ExitLinkQueue(&tLinkQueue,&cElementData);
     49     printf("退出队列元素:%d
    ",cElementData);
     50     
     51     printf("退出队列结果:");
     52     TraverseLinkQueue(&tLinkQueue);
     53     
     54     return 0;
     55 }*/
     56 /*****************************************************************************
     57 -Fuction        : InitLinkQueue
     58 -Description    : InitLinkQueue
     59 -Input            : 
     60 -Output         : 
     61 -Return         : 
     62 * Modify Date      Version         Author           Modification
     63 * -----------------------------------------------
     64 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     65 ******************************************************************************/
     66 int InitLinkQueue(T_LinkQueue *i_ptLinkQueue)
     67 {
     68     int iRet=-1;
     69     i_ptLinkQueue->ptFront=(T_QueueElement *)malloc(sizeof(T_QueueElement));
     70     if(NULL==i_ptLinkQueue->ptFront)
     71     {
     72         iRet=-1;
     73         printf("InitLinkQueue Malloc err
    ");
     74         exit(-1);
     75     }
     76     else
     77     {
     78         i_ptLinkQueue->ptRear=i_ptLinkQueue->ptFront;
     79         i_ptLinkQueue->ptRear->ptNext=NULL;
     80         iRet=0;
     81     }
     82     return iRet;
     83 }
     84 /*****************************************************************************
     85 -Fuction        : EnterLinkQueue
     86 -Description    : 考虑满的问题,不满则考虑插入到里面没有元素
     87                   的情况,即空的情况也就是最开始的时候
     88 -Input            : 
     89 -Output         : 
     90 -Return         : 
     91 * Modify Date      Version         Author           Modification
     92 * -----------------------------------------------
     93 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     94 ******************************************************************************/
     95 int EnterLinkQueue(T_LinkQueue *i_ptLinkQueue,T_QueueDataElement i_tElement)
     96 {
     97     int iRet=-1;
     98     T_QueueElement *ptQueueNode=NULL;
     99     ptQueueNode=(T_QueueElement *)malloc(sizeof(T_QueueElement));
    100     if(NULL==ptQueueNode)
    101     {
    102         iRet=-1;
    103         printf("EnterLinkQueue Malloce err");
    104     }
    105     else
    106     {    
    107         memcpy(&ptQueueNode->tData,&i_tElement,sizeof(T_QueueElement));//最开始ptRear指向头结点
    108         ptQueueNode->ptNext=NULL;//头结点不放元素
    109         i_ptLinkQueue->ptRear->ptNext=ptQueueNode;//所以只能放在头结点的下一个元素
    110         i_ptLinkQueue->ptRear=ptQueueNode;
    111         iRet=0;
    112     }
    113     return iRet;
    114 }
    115 /*****************************************************************************
    116 -Fuction        : ExitLinkQueue
    117 -Description    : 考虑空的问题,不空则考虑删除的是最后一个
    118                   元素的情况,即删除后为空的情况
    119 -Input            : 
    120 -Output         : 
    121 -Return         : 
    122 * Modify Date      Version         Author           Modification
    123 * -----------------------------------------------
    124 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    125 ******************************************************************************/
    126 int ExitLinkQueue(T_LinkQueue *i_ptLinkQueue,T_QueueDataElement *o_ptElement)
    127 {
    128     int iRet=-1;
    129     T_QueueElement *ptQueueNode=NULL;
    130     if(i_ptLinkQueue->ptFront==i_ptLinkQueue->ptRear)
    131     {
    132         iRet=-1;
    133         printf("LinkQueueEmpty Exit err
    ");
    134     }
    135     else
    136     {
    137         ptQueueNode=i_ptLinkQueue->ptFront->ptNext;
    138         memcpy(o_ptElement,&ptQueueNode->tData,sizeof(T_QueueElement));
    139         i_ptLinkQueue->ptFront->ptNext=ptQueueNode->ptNext;//最开始时
    140         if(ptQueueNode==i_ptLinkQueue->ptRear)//当取出的是队列仅有的一个元素,即剩下只有队头元素(头结点)
    141         {//队列里没有元素了,则对头和队尾要相等
    142             i_ptLinkQueue->ptRear=i_ptLinkQueue->ptFront;//
    143         }
    144         else{
    145         }
    146         free(ptQueueNode);
    147         iRet=0;
    148     }
    149     return iRet;
    150 }
    151 /*****************************************************************************
    152 -Fuction        : ExitLinkQueue
    153 -Description    : 考虑空的问题,不空则考虑删除的是最后一个
    154                   元素的情况,即删除后为空的情况
    155 -Input            : 
    156 -Output         : 
    157 -Return         : 
    158 * Modify Date      Version         Author           Modification
    159 * -----------------------------------------------
    160 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    161 ******************************************************************************/
    162 int IsLinkQueueEmpty(T_LinkQueue *i_ptLinkQueue)
    163 {
    164     int iRet=-1;
    165     T_QueueElement *ptQueueNode=NULL;
    166     if(i_ptLinkQueue->ptFront!=i_ptLinkQueue->ptRear)
    167     {
    168         iRet=-1;
    169     }
    170     else
    171     {
    172         iRet=0;
    173     }
    174     return iRet;
    175 }
    176 
    177 /*****************************************************************************
    178 -Fuction        : TraverseLinkQueue
    179 -Description    : TraverseLinkQueue
    180 -Input            : 
    181 -Output         : 
    182 -Return         : 
    183 * Modify Date      Version         Author           Modification
    184 * -----------------------------------------------
    185 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    186 ******************************************************************************/
    187 static void TraverseLinkQueue(T_LinkQueue *i_ptLinkQueue)
    188 {
    189     T_QueueElement *ptQueueNode=NULL;
    190     ptQueueNode=i_ptLinkQueue->ptFront->ptNext;
    191     while(NULL!=ptQueueNode)
    192     {
    193         //printf("%d",ptQueueNode->tData);
    194         ptQueueNode=ptQueueNode->ptNext;
    195     }
    196     printf("
    ");
    197 }
    LinkQueue.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     LinkQueue.h
     5 * Description        :     LinkQueue operation center
     6 * Created            :     2017.04.24.
     7 * Author            :     Yu Weifeng
     8 * Function List         :     
     9 * Last Modified     :     
    10 * History            :     
    11 ******************************************************************************/
    12 #ifndef _LINK_QUEUE_H
    13 #define _LINK_QUEUE_H
    14 
    15 //#include "ChildSiblingTree.h"
    16 typedef struct QueueDataElement
    17 {
    18 //    T_ChildSiblingTreeNode *ptData;
    19     int iData;
    20 }T_QueueDataElement,*PT_QueueDataElement;
    21 
    22 
    23 typedef struct QueueElement
    24 {
    25     T_QueueDataElement tData;
    26     struct QueueElement *ptNext;
    27 }T_QueueElement,*PT_QueueElement;
    28 
    29 typedef struct LinkQueue
    30 {
    31     T_QueueElement *ptFront;
    32     T_QueueElement *ptRear;
    33 }T_LinkQueue,*PT_LinkQueue;
    34 
    35 
    36 
    37 int InitLinkQueue(T_LinkQueue *i_pptLinkQueue);
    38 int EnterLinkQueue(T_LinkQueue *i_ptLinkQueue,T_QueueDataElement i_tElement);
    39 int ExitLinkQueue(T_LinkQueue *i_ptLinkQueue,T_QueueDataElement *o_ptElement);
    40 
    41 #endif
    LinkQueue.h

    2)顺序队列

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     SequenceQueue.c
      5 * Description        :     SequenceQueue operation center
      6 顺序表示的队列一定是循环队列
      7 因为顺序表示的队列要使用已经出队的空间就必须使用
      8 循环的方法指向已经出队的空间
      9 * Created            :     2017.04.24.
     10 * Author            :     Yu Weifeng
     11 * Function List         :     
     12 * Last Modified     :     
     13 * History            :     
     14 ******************************************************************************/
     15 #include"stdio.h"
     16 #include"malloc.h"
     17 #include"stdlib.h"
     18 #include"string.h"
     19 
     20 typedef struct SeqQueueElement//顺序队列结点里只有数据元素
     21 {
     22     char cData;
     23 }T_SeqQueueElement,*PT_SeqQueueElement;//结点等同于数据元素
     24 
     25 typedef struct SeqQueue
     26 {
     27     T_SeqQueueElement *ptBase;//所以为了方便,直接队列元素代替队列结点
     28     int iFront;
     29     int iRear;
     30 }T_SeqQueue,*PT_SeqQueue;
     31 
     32 #define SEQUENCE_QUEUE_MAX_LEN    5
     33 static int InitSeqQueue(T_SeqQueue *i_ptSeqQueue);
     34 static int EnterSeqQueue(T_SeqQueue *i_ptSeqQueue,T_SeqQueueElement i_tElement);
     35 static int ExitSeqQueue(T_SeqQueue *i_ptSeqQueue,T_SeqQueueElement *o_ptElement);
     36 static void TraverseSeqQueue(T_SeqQueue *i_ptSeqQueue);
     37 
     38 /*****************************************************************************
     39 -Fuction        : main
     40 -Description    : main
     41 -Input            : 
     42 -Output         : 
     43 -Return         : 
     44 * Modify Date      Version         Author           Modification
     45 * -----------------------------------------------
     46 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     47 ******************************************************************************/
     48 int main(int argc,char **argv)
     49 {
     50     T_SeqQueue tSeqQueue={0};
     51     T_SeqQueueElement tElementData={0};
     52     InitSeqQueue(&tSeqQueue);
     53     tElementData.cData=1;
     54     EnterSeqQueue(&tSeqQueue,tElementData);
     55     tElementData.cData=2;
     56     EnterSeqQueue(&tSeqQueue,tElementData);
     57     tElementData.cData=5;
     58     EnterSeqQueue(&tSeqQueue,tElementData);
     59     tElementData.cData=6;
     60     EnterSeqQueue(&tSeqQueue,tElementData);
     61     printf("进入队列结果:");
     62     TraverseSeqQueue(&tSeqQueue);
     63     
     64     ExitSeqQueue(&tSeqQueue,&tElementData);
     65     printf("退出队列元素:%d
    ",tElementData.cData);
     66     ExitSeqQueue(&tSeqQueue,&tElementData);
     67     printf("退出队列元素:%d
    ",tElementData.cData);
     68     ExitSeqQueue(&tSeqQueue,&tElementData);
     69     printf("退出队列元素:%d
    ",tElementData.cData);
     70     
     71     printf("退出队列结果:");
     72     TraverseSeqQueue(&tSeqQueue);
     73     return 0;
     74 }
     75 /*****************************************************************************
     76 -Fuction        : InitSeqQueue
     77 -Description    : InitSeqQueue
     78 -Input            : 
     79 -Output         : 
     80 -Return         : 
     81 * Modify Date      Version         Author           Modification
     82 * -----------------------------------------------
     83 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     84 ******************************************************************************/
     85 static int InitSeqQueue(T_SeqQueue *i_ptSeqQueue)
     86 {
     87     int iRet=-1;
     88     i_ptSeqQueue->ptBase=(T_SeqQueueElement *)malloc(sizeof(T_SeqQueueElement)*SEQUENCE_QUEUE_MAX_LEN);
     89     if(NULL==i_ptSeqQueue->ptBase)
     90     {
     91         printf("InitSeqQueue MallocErr
    ");
     92         exit(-1);
     93     }
     94     else
     95     {
     96         i_ptSeqQueue->iRear=i_ptSeqQueue->iFront=0;
     97         iRet=0;
     98     }
     99     return iRet;
    100 }
    101 
    102 /*****************************************************************************
    103 -Fuction        : EnterSeqQueue
    104 -Description    : 考虑满的问题,不满则考虑插入到里面没有元素
    105                   的情况,即空的情况也就是最开始的时候
    106 -Input            : 
    107 -Output         : 
    108 -Return         : 
    109 * Modify Date      Version         Author           Modification
    110 * -----------------------------------------------
    111 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    112 ******************************************************************************/
    113 static int EnterSeqQueue(T_SeqQueue *i_ptSeqQueue,T_SeqQueueElement i_tElement)
    114 {
    115     int iRet=-1;
    116     if((i_ptSeqQueue->iRear+1)%SEQUENCE_QUEUE_MAX_LEN==i_ptSeqQueue->iFront)
    117     {//要放元素的下一个位置,即队尾的下一个位置如果等于队头则满
    118         printf("EnterSeqQueue err,SeqQueueFull
    ");
    119         iRet=-1;
    120     }
    121     else
    122     {
    123         i_ptSeqQueue->ptBase[i_ptSeqQueue->iRear]=i_tElement;//iRear指向待放元素的位置
    124         i_ptSeqQueue->iRear=(i_ptSeqQueue->iRear+1)%SEQUENCE_QUEUE_MAX_LEN;
    125         iRet=0;
    126     }
    127     return iRet;
    128 }
    129 
    130 /*****************************************************************************
    131 -Fuction        : ExitSeqQueue
    132 -Description    : 考虑空的问题,不空则考虑删除的是最后一个
    133                   元素的情况,即删除后为空的情况
    134 -Input            : 
    135 -Output         : 
    136 -Return         : 
    137 * Modify Date      Version         Author           Modification
    138 * -----------------------------------------------
    139 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    140 ******************************************************************************/
    141 static int ExitSeqQueue(T_SeqQueue *i_ptSeqQueue,T_SeqQueueElement *o_ptElement)
    142 {
    143     int iRet=-1;
    144     if(i_ptSeqQueue->iFront==i_ptSeqQueue->iRear)
    145     {
    146         printf("EnterSeqQueue err,SeqQueueEmpty
    ");
    147     }
    148     else
    149     {
    150         *o_ptElement=i_ptSeqQueue->ptBase[i_ptSeqQueue->iFront];
    151         i_ptSeqQueue->iFront=(i_ptSeqQueue->iFront+1)%SEQUENCE_QUEUE_MAX_LEN;
    152         iRet=0;
    153     }
    154     return iRet;
    155 }
    156 /*****************************************************************************
    157 -Fuction        : TraverseSeqQueue
    158 -Description    : 遍历直到最后一个元素,所以其中循环条件一般考虑
    159                   最后一个元素时的情形
    160 -Input            : 
    161 -Output         : 
    162 -Return         : 
    163 * Modify Date      Version         Author           Modification
    164 * -----------------------------------------------
    165 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    166 ******************************************************************************/
    167 static void TraverseSeqQueue(T_SeqQueue *i_ptSeqQueue)
    168 {
    169     int i=i_ptSeqQueue->iFront;
    170     while(i!=i_ptSeqQueue->iRear)
    171     {
    172         printf("%d ",i_ptSeqQueue->ptBase[i].cData);
    173         i=(i+1)%SEQUENCE_QUEUE_MAX_LEN;
    174     }
    175     printf("
    ");
    176 }
    SequenceQueue.c

    3.栈

    1)顺序栈

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     SequenceStack.c
      5 * Description        :     SequenceStack operation center
      6 * Created            :     2017.04.22.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 typedef struct StackElement
     18 {
     19     T_LinkBiTreeNode *ptData;
     20     
     21 }T_StackElement,*PT_StackElement;
     22 typedef struct SeqStack
     23 {
     24     T_StackElement *ptBase; 
     25     T_StackElement *ptTop; 
     26     int iLen;
     27 }T_SeqStack,*PT_SeqStack;
     28 
     29 #define MAX_STACK_LENGTH                100
     30 #define INCREMENT_STACK_LENGTH        (2)
     31 
     32 /*****************************************************************************
     33 -Fuction        : InitStack
     34 -Description    : InitStack
     35 -Input            : 
     36 -Output         : 
     37 -Return         : 
     38 * Modify Date      Version         Author           Modification
     39 * -----------------------------------------------
     40 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     41 ******************************************************************************/
     42 static int InitSeqStack(T_SeqStack *i_ptSeqStack)
     43 {
     44     int iRet=-1;
     45     i_ptSeqStack->ptBase=(T_StackElement *)malloc(MAX_STACK_LENGTH*sizeof(T_StackElement));
     46     if(NULL==i_ptSeqStack->ptBase)
     47     {
     48         iRet=-1;
     49         printf("mallocFail,InitStack err");
     50         exit(-1);
     51     }
     52     else
     53     {
     54         i_ptSeqStack->ptTop=i_ptSeqStack->ptBase;
     55         i_ptSeqStack->iLen=MAX_STACK_LENGTH;
     56         iRet=0;
     57     }
     58     return iRet;
     59 }
     60 
     61 /*****************************************************************************
     62 -Fuction        : Push
     63 -Description    : Push
     64 -Input            : 
     65 -Output         : 
     66 -Return         : 
     67 * Modify Date      Version         Author           Modification
     68 * -----------------------------------------------
     69 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     70 ******************************************************************************/
     71 static int PushSeqStack(T_SeqStack *i_ptSeqStack,T_StackElement *i_ptStackElement)
     72 {
     73     int iRet=-1;
     74     if((i_ptSeqStack->ptTop-i_ptSeqStack->ptBase)==i_ptSeqStack->iLen)
     75     {//追加内存,返回地址可能是新的,但是原来的内容保持不变(会拷贝)
     76         i_ptSeqStack->ptBase=(T_StackElement *)realloc(i_ptSeqStack->ptBase,(i_ptSeqStack->iLen+INCREMENT_STACK_LENGTH)*
     77                             sizeof(T_StackElement));
     78         if(NULL==i_ptSeqStack->ptBase)
     79         {
     80             iRet=-1;
     81             printf("StackFull,ReallocFail,Push err");
     82             exit(-1);
     83         }
     84         else
     85         {//返回内存地址可能会变,不是原先的了
     86             i_ptSeqStack->ptTop=i_ptSeqStack->ptBase+i_ptSeqStack->iLen;
     87             i_ptSeqStack->iLen=i_ptSeqStack->iLen+INCREMENT_STACK_LENGTH;
     88         }
     89     }
     90     else
     91     {
     92     }
     93     memcpy(i_ptSeqStack->ptTop,i_ptStackElement,sizeof(T_StackElement));
     94     i_ptSeqStack->ptTop++;
     95     iRet=0;
     96     return iRet;
     97 }
     98 
     99 /*****************************************************************************
    100 -Fuction        : Pop
    101 -Description    : Pop
    102 -Input            : 
    103 -Output         : 
    104 -Return         : 
    105 * Modify Date      Version         Author           Modification
    106 * -----------------------------------------------
    107 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    108 ******************************************************************************/
    109 static int PopSeqStack(T_SeqStack *i_ptSeqStack,T_StackElement *o_ptStackElement)
    110 {
    111     int iRet=-1;
    112     if(i_ptSeqStack->ptTop==i_ptSeqStack->ptBase)
    113     {
    114         iRet=-1;
    115         printf("StackEmpty,Pop err");
    116     }
    117     else
    118     {
    119         i_ptSeqStack->ptTop--;
    120         memcpy(o_ptStackElement,i_ptSeqStack->ptTop,sizeof(T_StackElement));
    121         iRet=0;
    122     }
    123     return iRet;
    124 }
    125 
    126 
    127 /*****************************************************************************
    128 -Fuction        : SeqStackEmpty
    129 -Description    : SeqStackEmpty
    130 -Input            : 
    131 -Output         : 
    132 -Return         : 
    133 * Modify Date      Version         Author           Modification
    134 * -----------------------------------------------
    135 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    136 ******************************************************************************/
    137 static int IsSeqStackEmpty(T_SeqStack *i_ptSeqStack)
    138 {
    139     int iRet=-1;
    140     if(i_ptSeqStack->ptTop==i_ptSeqStack->ptBase)
    141     {
    142         iRet=0;
    143         //printf("StackEmpty
    ");
    144     }
    145     else
    146     {
    147         iRet=-1;
    148     }
    149     return iRet;
    150 }
    151 
    152 
    153 /*****************************************************************************
    154 -Fuction        : GetSeqStackTopElement
    155 -Description    : 
    156 // 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
    157 -Input            : 
    158 -Output         : 
    159 -Return         : 
    160 * Modify Date      Version         Author           Modification
    161 * -----------------------------------------------
    162 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    163 ******************************************************************************/
    164 static int GetSeqStackTopElement(T_SeqStack *i_ptSeqStack,T_StackElement *o_ptStackElement)
    165 {
    166     int iRet=-1;
    167     if(i_ptSeqStack->ptTop>i_ptSeqStack->ptBase)
    168     {
    169          memcpy(o_ptStackElement,i_ptSeqStack->ptTop-1,sizeof(T_StackElement));
    170          iRet=0;
    171     }
    172     else
    173     {
    174         iRet=-1;
    175     }
    176     return iRet;
    177 }
    SequenceStack.c

    2)栈的应用(走迷宫)

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     DualLinkList.c
      5 * Description        :     DualLinkList operation center
      6 * Created            :     2017.04.22.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 typedef struct MazePosType
     18 {
     19     int x;
     20     int y;
     21 }T_MazePosType,*PT_MazePosType;
     22 typedef struct StackElement
     23 {
     24     int iOrder;
     25     T_MazePosType tPos;
     26     int iDirection;
     27 }T_StackElement,*PT_StackElement;
     28 typedef struct SeqStack
     29 {
     30     T_StackElement *ptBase; 
     31     T_StackElement *ptTop; 
     32     int iLen;
     33 }T_SeqStack,*PT_SeqStack;
     34 
     35 #define MAX_MAZE_LENGTH                25
     36 #define MAX_STACK_LENGTH                (MAX_MAZE_LENGTH*MAX_MAZE_LENGTH)
     37 #define INCREMENT_STACK_LENGTH        (2)
     38 
     39 static int InitStack(T_SeqStack *i_ptSeqStack);
     40 static int Push(T_SeqStack *i_ptSeqStack,T_StackElement *i_ptStackElement);
     41 static int Pop(T_SeqStack *i_ptSeqStack,T_StackElement *o_ptStackElement);
     42 static int StackEmpty(T_SeqStack *i_ptSeqStack);
     43 
     44 static void PrintMaze(int i_daiMaze[][MAX_MAZE_LENGTH],int i_iX,int i_iY);
     45 static void InitMaze(int i_dwPassValue,int i_daiMaze[][MAX_MAZE_LENGTH],int *o_piX,int *o_piY,T_MazePosType *ptBeginPos,T_MazePosType *ptEndPos);
     46 static int PassJudge(int i_daiMaze[][MAX_MAZE_LENGTH],T_MazePosType *i_ptMazePos);
     47 static void FootMark(int i_daiMaze[][MAX_MAZE_LENGTH],T_MazePosType *i_ptMazePos,int i_iCurStep);
     48 static void NextPos(T_MazePosType *i_ptMazePos,int i_iDirection);
     49 static void NoWayMark(int i_daiMaze[][MAX_MAZE_LENGTH],T_MazePosType *i_ptMazePos);
     50 
     51 
     52 /*****************************************************************************
     53 -Fuction        : main
     54 -Description    : main
     55 -Input            : 
     56 -Output         : 
     57 -Return         : 
     58 * Modify Date      Version         Author           Modification
     59 * -----------------------------------------------
     60 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     61 ******************************************************************************/
     62 int main(int argc,char **argv)
     63 {
     64     int aMaze[MAX_MAZE_LENGTH][MAX_MAZE_LENGTH]={0};
     65     int iRowNum,iRankNum;
     66     T_MazePosType tBeginPos={0};
     67     T_MazePosType tEndPos={0};
     68     InitMaze(1,aMaze,&iRowNum,&iRankNum,&tBeginPos,&tEndPos);
     69     if(0==MazePath(aMaze,&tBeginPos,&tEndPos))
     70     {
     71         printf("从入口到出口一条通路如下:
    ");
     72         PrintMaze(aMaze,iRowNum,iRankNum);
     73     }
     74     else
     75     {
     76         printf("此迷宫没有通路
    ");
     77     }
     78     
     79     return 0;
     80 }
     81 
     82 /*****************************************************************************
     83 -Fuction        : MazePath
     84 -Description    : 当前位置不是墙直接入栈直到终点,不是终点
     85 继续下个位置。当前位置是墙,如果栈不为空,出栈找到
     86 墙的前一个位置,如果这个位置四个方向都走过了不通并且
     87 栈不空,继续出栈找到前一个位置还有方向没走过的,
     88 找到后换方向,换下一位置继续判断
     89 同时由于该位置不是墙(前面判断过了)所以继续入栈
     90 -Input            : 
     91 -Output         : 
     92 -Return         : 
     93 * Modify Date      Version         Author           Modification
     94 * -----------------------------------------------
     95 * 2017/04/21      V1.0.0         Yu Weifeng       Created
     96 ******************************************************************************/
     97 int MazePath(int i_daiMaze[][MAX_MAZE_LENGTH],T_MazePosType *i_ptBeginPos,T_MazePosType *i_ptEndPos)
     98 {
     99     T_MazePosType tCurrentPos={0};
    100     int iCurrentStep=1;//为1第一个位置,防止与0的墙混淆
    101     T_SeqStack tSeqStack;
    102     T_StackElement tStackElement={0};
    103     memcpy(&tCurrentPos,i_ptBeginPos,sizeof(T_MazePosType));
    104     InitStack(&tSeqStack);
    105     do
    106     {
    107         if(0==PassJudge(i_daiMaze,&tCurrentPos))//当前位置不是墙
    108         {
    109             FootMark(i_daiMaze,&tCurrentPos,iCurrentStep);
    110             tStackElement.iOrder=iCurrentStep;
    111             tStackElement.tPos=tCurrentPos;
    112             tStackElement.iDirection=0;
    113             Push(&tSeqStack,&tStackElement);                
    114             iCurrentStep++;
    115             if((tCurrentPos.x==i_ptEndPos->x)&&(tCurrentPos.y==i_ptEndPos->y))
    116             return 0;
    117             NextPos(&tCurrentPos,tStackElement.iDirection);
    118             //printf("Line:%d,Step:%d,x:%d,y:%d
    ", __LINE__,iCurrentStep,tStackElement.tPos.x,tStackElement.tPos.y);
    119         }
    120         else// 当前位置不能通过,是墙(当前位置没入栈,墙没法走不入栈)
    121         {
    122             if(0!=StackEmpty(&tSeqStack))
    123             {
    124                 Pop(&tSeqStack,&tStackElement);     // 退栈找到前一位置(墙前一个位置)
    125                 iCurrentStep--;// 足迹减1
    126                 while((tStackElement.iDirection==3)&&(0!=StackEmpty(&tSeqStack)))// 前一位置处于最后一个方向(北)
    127                 {
    128                     NoWayMark(i_daiMaze,&tStackElement.tPos);//走不通,没法走了,不入栈,出栈掉
    129                     Pop(&tSeqStack,&tStackElement);     
    130                     iCurrentStep--;// 足迹减1
    131                 }
    132                 if(tStackElement.iDirection<3)
    133                 {
    134                     tStackElement.iDirection++;
    135                     iCurrentStep++;
    136                     tCurrentPos=tStackElement.tPos;
    137                     NextPos(&tCurrentPos,tStackElement.iDirection);
    138                     Push(&tSeqStack,&tStackElement);//(不是墙,换了方向)可以走,入栈
    139                 }
    140                 else{
    141                 }
    142             }
    143             else
    144             {
    145             }
    146         }
    147     }while(0!=StackEmpty(&tSeqStack));
    148     return -1;
    149 }
    150 /*****************************************************************************
    151 -Fuction        : PrintMaze
    152 -Description    : PrintMaze
    153 -Input            : 
    154 -Output         : 
    155 -Return         : 
    156 * Modify Date      Version         Author           Modification
    157 * -----------------------------------------------
    158 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    159 ******************************************************************************/
    160 static void PrintMaze(int i_daiMaze[][MAX_MAZE_LENGTH],int i_iX,int i_iY)
    161 {
    162     int i,j;
    163     for(i=0;i<i_iX;i++)
    164     {
    165         for(j=0;j<i_iY;j++)
    166         {
    167             printf("%3d",i_daiMaze[i][j]);
    168         }
    169         printf("
    ");
    170     }
    171 }
    172 /*****************************************************************************
    173 -Fuction        : InitMaze
    174 -Description    : InitMaze
    175 -Input            : 
    176 -Output         : 
    177 -Return         : 
    178 * Modify Date      Version         Author           Modification
    179 * -----------------------------------------------
    180 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    181 ******************************************************************************/
    182 static void InitMaze(int i_dwPassValue,int i_daiMaze[][MAX_MAZE_LENGTH],int *o_piX,int *o_piY,T_MazePosType *ptBeginPos,T_MazePosType *ptEndPos)
    183 {
    184     int i,j,x,y;
    185     int iWallNum=0;
    186     int iWallX=0,iWallY=0;
    187     printf("请输入迷宫的行数,列数(包括外墙):");
    188     scanf("%d,%d",&x,&y);
    189     *o_piX=x;
    190     *o_piY=y;
    191     for(i=0;i<y;i++)//外墙全为0
    192     {
    193         i_daiMaze[0][i]=0;
    194         i_daiMaze[x-1][i]=0;
    195     }
    196     for(i=1;i<x-1;i++)
    197     {
    198         i_daiMaze[i][0]=0;
    199         i_daiMaze[i][y-1]=0;
    200     }
    201     for(i=1;i<x-1;i++)// 定义除外墙,其余都是通道,初值为k
    202     {
    203         for(j=1;j<y-1;j++)
    204         {
    205             i_daiMaze[i][j]=i_dwPassValue;
    206         }
    207     }
    208     printf("请输入迷宫内墙单元数:");
    209     scanf("%d",&iWallNum);
    210     printf("请依次输入迷宫内墙每个单元的行数,列数:
    ");
    211     for(i=0;i<iWallNum;i++)
    212     {
    213         scanf("%d,%d",&iWallX,&iWallY);
    214         i_daiMaze[iWallX][iWallY]=0;// 修改墙的值为0
    215     }
    216     printf("迷宫结构如下:
    ");
    217     PrintMaze(i_daiMaze,x,y);
    218     printf("请输入入口的行数,列数:");
    219     scanf("%d,%d",&ptBeginPos->x,&ptBeginPos->y);
    220     printf("请输入出口的行数,列数:");
    221     scanf("%d,%d",&ptEndPos->x,&ptEndPos->y);
    222 }
    223 /*****************************************************************************
    224 -Fuction        : PassJudge
    225 -Description    : PassJudge
    226 -Input            : 
    227 -Output         : 
    228 -Return         : 
    229 * Modify Date      Version         Author           Modification
    230 * -----------------------------------------------
    231 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    232 ******************************************************************************/
    233 static int PassJudge(int i_daiMaze[][MAX_MAZE_LENGTH],T_MazePosType *i_ptMazePos)
    234 {
    235     int iRet=-1;
    236     if(i_daiMaze[i_ptMazePos->x][i_ptMazePos->y]!=1)
    237     {
    238         iRet=-1;
    239     }
    240     else
    241     {
    242         iRet=0;
    243     }
    244     return iRet;
    245 }
    246 /*****************************************************************************
    247 -Fuction        : FootMark
    248 -Description    : FootMark
    249 -Input            : 
    250 -Output         : 
    251 -Return         : 
    252 * Modify Date      Version         Author           Modification
    253 * -----------------------------------------------
    254 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    255 ******************************************************************************/
    256 static void FootMark(int i_daiMaze[][MAX_MAZE_LENGTH],T_MazePosType *i_ptMazePos,int i_iCurStep)
    257 {
    258     i_daiMaze[i_ptMazePos->x][i_ptMazePos->y]=i_iCurStep;
    259 }
    260 /*****************************************************************************
    261 -Fuction        : NextPos
    262 -Description    : NextPos
    263 -Input            : 
    264 -Output         : 
    265 -Return         : 
    266 * Modify Date      Version         Author           Modification
    267 * -----------------------------------------------
    268 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    269 ******************************************************************************/
    270 static void NextPos(T_MazePosType *i_ptMazePos,int i_iDirection)
    271 {
    272     static T_MazePosType s_atMazePos[4]={{0,1},{1,0},{0,-1},{-1,0}};// {行增量,列增量},移动方向,依次为东南西北
    273     i_ptMazePos->x+=s_atMazePos[i_iDirection].x;
    274     i_ptMazePos->y+=s_atMazePos[i_iDirection].y;
    275 }
    276 /*****************************************************************************
    277 -Fuction        : NoWayMark
    278 -Description    : NoWayMark
    279 -Input            : 
    280 -Output         : 
    281 -Return         : 
    282 * Modify Date      Version         Author           Modification
    283 * -----------------------------------------------
    284 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    285 ******************************************************************************/
    286 static void NoWayMark(int i_daiMaze[][MAX_MAZE_LENGTH],T_MazePosType *i_ptMazePos)
    287 {
    288     i_daiMaze[i_ptMazePos->x][i_ptMazePos->y]=-1;
    289 
    290 }
    291 /*****************************************************************************
    292 -Fuction        : InitStack
    293 -Description    : InitStack
    294 -Input            : 
    295 -Output         : 
    296 -Return         : 
    297 * Modify Date      Version         Author           Modification
    298 * -----------------------------------------------
    299 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    300 ******************************************************************************/
    301 static int InitStack(T_SeqStack *i_ptSeqStack)
    302 {
    303     int iRet=-1;
    304     i_ptSeqStack->ptBase=(T_StackElement *)malloc(MAX_STACK_LENGTH*sizeof(T_StackElement));
    305     if(NULL==i_ptSeqStack->ptBase)
    306     {
    307         iRet=-1;
    308         printf("mallocFail,InitStack err");
    309         exit(-1);
    310     }
    311     else
    312     {
    313         i_ptSeqStack->ptTop=i_ptSeqStack->ptBase;
    314         i_ptSeqStack->iLen=MAX_MAZE_LENGTH;
    315         iRet=0;
    316     }
    317     return iRet;
    318 }
    319 
    320 /*****************************************************************************
    321 -Fuction        : Push
    322 -Description    : Push
    323 -Input            : 
    324 -Output         : 
    325 -Return         : 
    326 * Modify Date      Version         Author           Modification
    327 * -----------------------------------------------
    328 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    329 ******************************************************************************/
    330 static int Push(T_SeqStack *i_ptSeqStack,T_StackElement *i_ptStackElement)
    331 {
    332     int iRet=-1;
    333     if((i_ptSeqStack->ptTop-i_ptSeqStack->ptBase)==i_ptSeqStack->iLen)
    334     {//追加内存,返回地址可能是新的,但是原来的内容保持不变(会拷贝)
    335         i_ptSeqStack->ptBase=(T_StackElement *)realloc(i_ptSeqStack->ptBase,(i_ptSeqStack->iLen+INCREMENT_STACK_LENGTH)*
    336                             sizeof(T_StackElement));
    337         if(NULL==i_ptSeqStack->ptBase)
    338         {
    339             iRet=-1;
    340             printf("StackFull,ReallocFail,Push err");
    341             exit(-1);
    342         }
    343         else
    344         {//返回内存地址可能会变,不是原先的了
    345             i_ptSeqStack->ptTop=i_ptSeqStack->ptBase+i_ptSeqStack->iLen;
    346             i_ptSeqStack->iLen=i_ptSeqStack->iLen+INCREMENT_STACK_LENGTH;
    347         }
    348     }
    349     else
    350     {
    351     }
    352     memcpy(i_ptSeqStack->ptTop,i_ptStackElement,sizeof(T_StackElement));
    353     i_ptSeqStack->ptTop++;
    354     iRet=0;
    355     return iRet;
    356 }
    357 
    358 /*****************************************************************************
    359 -Fuction        : Pop
    360 -Description    : Pop
    361 -Input            : 
    362 -Output         : 
    363 -Return         : 
    364 * Modify Date      Version         Author           Modification
    365 * -----------------------------------------------
    366 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    367 ******************************************************************************/
    368 static int Pop(T_SeqStack *i_ptSeqStack,T_StackElement *o_ptStackElement)
    369 {
    370     int iRet=-1;
    371     if(i_ptSeqStack->ptTop==i_ptSeqStack->ptBase)
    372     {
    373         iRet=-1;
    374         printf("StackEmpty,Pop err");
    375     }
    376     else
    377     {
    378         i_ptSeqStack->ptTop--;
    379         memcpy(o_ptStackElement,i_ptSeqStack->ptTop,sizeof(T_StackElement));
    380         iRet=0;
    381     }
    382     return iRet;
    383 }
    384 
    385 
    386 /*****************************************************************************
    387 -Fuction        : Pop
    388 -Description    : Pop
    389 -Input            : 
    390 -Output         : 
    391 -Return         : 
    392 * Modify Date      Version         Author           Modification
    393 * -----------------------------------------------
    394 * 2017/04/21      V1.0.0         Yu Weifeng       Created
    395 ******************************************************************************/
    396 static int StackEmpty(T_SeqStack *i_ptSeqStack)
    397 {
    398     int iRet=-1;
    399     if(i_ptSeqStack->ptTop==i_ptSeqStack->ptBase)
    400     {
    401         iRet=0;
    402         printf("StackEmpty
    ");
    403     }
    404     else
    405     {
    406         iRet=-1;
    407     }
    408     return iRet;
    409 }
    StackUsedForMazePath.c

    4.二叉树与树

    1)链式二叉树

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     LinkBiTree.c
      5 * Description        :     LinkBiTree operation center
      6 * Created            :     2017.05.11.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include "stdio.h"
     13 #include "malloc.h"
     14 #include "stdlib.h"
     15 #include "string.h"
     16 #include "math.h"
     17 #include "LinkBiTree.h"
     18 #include "LinkQueue.c"
     19 #include "SequenceStack.c"
     20 
     21 
     22 
     23 
     24 
     25 static void InitLinkBiTree(T_LinkBiTreeNode **i_pptLinkBiTree);
     26 static void DestroyLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree);
     27 static int IsLinkBiTreeEmpty(T_LinkBiTreeNode *i_ptLinkBiTree);
     28 static int GetLinkBiTreeDepth(T_LinkBiTreeNode *i_ptLinkBiTree);
     29 static char GetLinkBiTreeRootData(T_LinkBiTreeNode *i_ptLinkBiTree);
     30 static char GetLinkBiTreeNodeData(T_LinkBiTreeNode *i_ptLinkBiTreeNode);
     31 static void AssignToLinkBiTreeNode(T_LinkBiTreeNode *i_ptLinkBiTreeNode,char i_cData);
     32 
     33 static char GetLinkBiTreeParentData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData);
     34 static char GetLinkBiTreeLeftChildData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData);
     35 static char GetLinkBiTreeRightChildData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData);
     36 static char GetLinkBiTreeLeftSiblingData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData);
     37 static char GetLinkBiTreeRightSiblingData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData);
     38 
     39 
     40 static int CreateLinkBiTree(T_LinkBiTreeNode **i_pptLinkBiTree);
     41 static T_LinkBiTreeNode *GetLinkBiTreeNodePoint(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData);
     42 static int InsertChildInLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTreeNode,int i_iLeftOrRight,T_LinkBiTreeNode *i_ptInsertLinkBiTree);
     43 static int DeleteChildInLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTreeNode,int i_iLeftOrRight);
     44 static void PreOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree);
     45 static void InOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree);
     46 static void PostOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree);
     47 static void LevelOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree);
     48 static void UseStackInOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree);
     49 static void OptimizeUseStackInOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree);
     50 
     51 #define ClearLinkBiTree     DestroyLinkBiTree     // 清空二叉树和销毁二叉树的操作一样
     52 #define     NIL     ' '
     53 /*****************************************************************************
     54 -Fuction        : main
     55 -Description    : main
     56 -Input            : 
     57 -Output         : 
     58 -Return         : 
     59 * Modify Date      Version         Author           Modification
     60 * -----------------------------------------------
     61 * 2017/05/15      V1.0.0         Yu Weifeng       Created
     62 ******************************************************************************/
     63 int main(int argc,char **argv)
     64 {
     65     T_LinkBiTreeNode *ptLinkBiTree=NULL;    
     66     T_LinkBiTreeNode *ptLinkBiTreeNoRightChild=NULL;
     67     T_LinkBiTreeNode *ptLinkBiTreeNode=NULL;
     68     int iLeftOrRight=0;
     69     char cData;
     70     char cOtherData;
     71     InitLinkBiTree(&ptLinkBiTree);
     72     printf("构造空二叉树后,树空否?%d(0:是1:否)树的深度=%d
    ",IsLinkBiTreeEmpty(ptLinkBiTree),GetLinkBiTreeDepth(ptLinkBiTree));
     73     cData=GetLinkBiTreeRootData(ptLinkBiTree);
     74     if(cData!=NIL)
     75     printf("二叉树的根为%c
    ",cData);
     76     else
     77     printf("树空,无根
    ");
     78     printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)
    ");
     79     CreateLinkBiTree(&ptLinkBiTree);
     80     printf("构造二叉树后,树空否?%d(0:是1:否)树的深度=%d
    ",IsLinkBiTreeEmpty(ptLinkBiTree),GetLinkBiTreeDepth(ptLinkBiTree));
     81     cData=GetLinkBiTreeRootData(ptLinkBiTree);
     82     if(cData!=NIL)
     83     printf("二叉树的根为%c
    ",cData);
     84     else
     85     printf("树空,无根
    ");
     86     printf("中序递归遍历二叉树:
    ");
     87     InOrderTraverseLinkBiTree(ptLinkBiTree);
     88     printf("
    后序递归遍历二叉树:
    ");
     89     PostOrderTraverseLinkBiTree(ptLinkBiTree);
     90 
     91     printf("
    请输入一个结点的值: ");
     92     scanf("%*c%c",&cData);//%*c吃掉回车符
     93     ptLinkBiTreeNode=GetLinkBiTreeNodePoint(ptLinkBiTree,cData); // p为e1的指针
     94     printf("结点的值为%c
    ",GetLinkBiTreeNodeData(ptLinkBiTreeNode));
     95     printf("欲改变此结点的值,请输入新值: ");
     96     scanf("%*c%c%*c",&cData); // 后一个%*c吃掉回车符,%*c不赋值任何变量,为调用CreateBiTree()做准备
     97     AssignToLinkBiTreeNode(ptLinkBiTreeNode,cData);//"*"表示该输入项读入后不赋予任何变量,即跳过该输入值
     98     printf("层序遍历二叉树:
    ");
     99     LevelOrderTraverseLinkBiTree(ptLinkBiTree);
    100 
    101     cOtherData=GetLinkBiTreeParentData(ptLinkBiTree,cData);
    102     if(cOtherData!=NIL)
    103     printf("%c的双亲是%c
    ",cData,cOtherData);
    104     else
    105     printf("%c没有双亲
    ",cData);
    106     cOtherData=GetLinkBiTreeLeftChildData(ptLinkBiTree,cData);
    107     if(cOtherData!=NIL)
    108     printf("%c的左孩子是%c
    ",cData,cOtherData);
    109     else
    110     printf("%c没有左孩子
    ",cData);
    111     cOtherData=GetLinkBiTreeRightChildData(ptLinkBiTree,cData);
    112     if(cOtherData!=NIL)
    113     printf("%c的右孩子是%c
    ",cData,cOtherData);
    114     else
    115     printf("%c没有右孩子
    ",cData);
    116     cOtherData=GetLinkBiTreeLeftSiblingData(ptLinkBiTree,cData);
    117     if(cOtherData!=NIL)
    118     printf("%c的左兄弟是%c
    ",cData,cOtherData);
    119     else
    120     printf("%c没有左兄弟
    ",cData);
    121     cOtherData=GetLinkBiTreeRightSiblingData(ptLinkBiTree,cData);
    122     if(cOtherData!=NIL)
    123     printf("%c的右兄弟是%c
    ",cData,cOtherData);
    124     else
    125     printf("%c没有右兄弟
    ",cData);
    126 
    127     
    128     InitLinkBiTree(&ptLinkBiTreeNoRightChild);
    129     printf("构造一个右子树为空的二叉树c:
    ");
    130     printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)
    ");
    131     CreateLinkBiTree(&ptLinkBiTreeNoRightChild);
    132     printf("先序递归遍历二叉树c:
    ");
    133     PreOrderTraverseLinkBiTree(ptLinkBiTreeNoRightChild);
    134     printf("
    层序遍历二叉树c:
    ");
    135     LevelOrderTraverseLinkBiTree(ptLinkBiTreeNoRightChild);
    136 
    137     printf("树c插到树T中,请输入树T中树c的双亲结点   c为左(0)或右(1)子树: ");
    138     scanf("%*c%c,%d",&cData,&iLeftOrRight);    
    139     ptLinkBiTreeNode=GetLinkBiTreeNodePoint(ptLinkBiTree,cData);  // p是T中树c的双亲结点指针
    140     InsertChildInLinkBiTree(ptLinkBiTreeNode,iLeftOrRight,ptLinkBiTreeNoRightChild);
    141     printf("先序递归遍历二叉树:
    ");
    142     PreOrderTraverseLinkBiTree(ptLinkBiTree);
    143     printf("
    中序非递归遍历二叉树:
    ");
    144     UseStackInOrderTraverseLinkBiTree(ptLinkBiTree);
    145     
    146     printf("删除子树,请输入待删除子树的双亲结点    左(0)或右(1)子树: ");
    147     scanf("%*c%c,%d",&cData,&iLeftOrRight);    
    148     ptLinkBiTreeNode=GetLinkBiTreeNodePoint(ptLinkBiTree,cData); 
    149     DeleteChildInLinkBiTree(ptLinkBiTreeNode,iLeftOrRight);
    150     printf("先序递归遍历二叉树:
    ");
    151     PreOrderTraverseLinkBiTree(ptLinkBiTree);
    152     printf("
    中序非递归遍历二叉树(另一种方法):
    ");
    153     OptimizeUseStackInOrderTraverseLinkBiTree(ptLinkBiTree);
    154     DestroyLinkBiTree(ptLinkBiTree);
    155 }
    156 
    157 
    158 
    159 
    160 
    161 /*****************************************************************************
    162 -Fuction        : InitLinkBiTree
    163 -Description    : InitLinkBiTree
    164 -Input            : 
    165 -Output         : 
    166 -Return         : 
    167 * Modify Date      Version         Author           Modification
    168 * -----------------------------------------------
    169 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    170 ******************************************************************************/
    171 static void InitLinkBiTree(T_LinkBiTreeNode **i_pptLinkBiTree)
    172 {
    173     *i_pptLinkBiTree=NULL;
    174 }
    175 /*****************************************************************************
    176 -Fuction        : CreateLinkBiTree
    177 -Description    : 按先序次序输入二叉树中结点的值(为字符型)
    178 -Input            : 
    179 -Output         : 
    180 -Return         : 
    181 * Modify Date      Version         Author           Modification
    182 * -----------------------------------------------
    183 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    184 ******************************************************************************/
    185 static int CreateLinkBiTree(T_LinkBiTreeNode **i_pptLinkBiTree)
    186 {
    187     int iRet=0;
    188     char cData;
    189     scanf("%c",&cData);
    190     if(cData==NIL)//Nil表示空(子)树
    191     {
    192         *i_pptLinkBiTree=NULL;
    193     }
    194     else
    195     {
    196         *i_pptLinkBiTree=(T_LinkBiTreeNode *)malloc(sizeof(T_LinkBiTreeNode));
    197         if(NULL==*i_pptLinkBiTree)
    198         {
    199             printf("CreateLinkBiTree malloc err
    ");
    200             iRet=-1;
    201         }
    202         else
    203         {
    204             (*i_pptLinkBiTree)->cData=cData;
    205             CreateLinkBiTree(&(*i_pptLinkBiTree)->ptLeftChild);
    206             CreateLinkBiTree(&(*i_pptLinkBiTree)->ptRightChild);
    207         }
    208     }
    209     return iRet;
    210 }
    211 /*****************************************************************************
    212 -Fuction        : DestroyLinkBiTree
    213 -Description    : DestroyLinkBiTree
    214 -Input            : 
    215 -Output         : 
    216 -Return         : 
    217 * Modify Date      Version         Author           Modification
    218 * -----------------------------------------------
    219 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    220 ******************************************************************************/
    221 static void DestroyLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree)
    222 {
    223     if(NULL==i_ptLinkBiTree)
    224     {
    225     }
    226     else
    227     {
    228         if(NULL==i_ptLinkBiTree->ptLeftChild)
    229         {
    230         }
    231         else
    232         {
    233             DestroyLinkBiTree(i_ptLinkBiTree->ptLeftChild);
    234         }
    235         if(NULL==i_ptLinkBiTree->ptRightChild)
    236         {
    237         }
    238         else
    239         {
    240             DestroyLinkBiTree(i_ptLinkBiTree->ptRightChild);
    241         }
    242         free(i_ptLinkBiTree);
    243         i_ptLinkBiTree=NULL;
    244     }
    245 }
    246 /*****************************************************************************
    247 -Fuction        : PreOrderTraverseLinkBiTree
    248 -Description    : PreOrderTraverseLinkBiTree
    249 -Input            : 
    250 -Output         : 
    251 -Return         : 
    252 * Modify Date      Version         Author           Modification
    253 * -----------------------------------------------
    254 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    255 ******************************************************************************/
    256 static void PreOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree)
    257 {
    258     if(NULL==i_ptLinkBiTree)
    259     {
    260     }
    261     else
    262     {
    263         printf("%c ",i_ptLinkBiTree->cData);
    264         PreOrderTraverseLinkBiTree(i_ptLinkBiTree->ptLeftChild);
    265         PreOrderTraverseLinkBiTree(i_ptLinkBiTree->ptRightChild);
    266     }
    267 }
    268 /*****************************************************************************
    269 -Fuction        : InOrderTraverseLinkBiTree
    270 -Description    : InOrderTraverseLinkBiTree
    271 -Input            : 
    272 -Output         : 
    273 -Return         : 
    274 * Modify Date      Version         Author           Modification
    275 * -----------------------------------------------
    276 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    277 ******************************************************************************/
    278 static void InOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree)
    279 {
    280     if(NULL==i_ptLinkBiTree)
    281     {
    282     }
    283     else
    284     {
    285         InOrderTraverseLinkBiTree(i_ptLinkBiTree->ptLeftChild);
    286         printf("%c ",i_ptLinkBiTree->cData);
    287         InOrderTraverseLinkBiTree(i_ptLinkBiTree->ptRightChild);
    288     }
    289 }
    290 /*****************************************************************************
    291 -Fuction        : PostOrderTraverseLinkBiTree
    292 -Description    : PostOrderTraverseLinkBiTree
    293 -Input            : 
    294 -Output         : 
    295 -Return         : 
    296 * Modify Date      Version         Author           Modification
    297 * -----------------------------------------------
    298 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    299 ******************************************************************************/
    300 static void PostOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree)
    301 {
    302     if(NULL==i_ptLinkBiTree)
    303     {
    304     }
    305     else
    306     {
    307         PostOrderTraverseLinkBiTree(i_ptLinkBiTree->ptLeftChild);
    308         PostOrderTraverseLinkBiTree(i_ptLinkBiTree->ptRightChild);
    309         printf("%c ",i_ptLinkBiTree->cData);
    310     }
    311 }
    312 /*****************************************************************************
    313 -Fuction        : LevelOrderTraverseLinkBiTree
    314 -Description    : 
    315 // 初始条件:二叉树T存在,Visit是对结点操作的应用函数
    316 // 操作结果:层序递归遍历T(利用队列),对每个结点调用函数Visit一次且仅一次
    317 -Input            : 
    318 -Output         : 
    319 -Return         : 
    320 * Modify Date      Version         Author           Modification
    321 * -----------------------------------------------
    322 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    323 ******************************************************************************/
    324 static void LevelOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree)
    325 {
    326     T_LinkQueue tLinkQueue={0};
    327     T_LinkBiTreeNode *ptBiTreeNode=NULL;
    328     T_QueueDataElement tQueueElement;
    329     InitLinkQueue(&tLinkQueue);
    330     tQueueElement.ptData=i_ptLinkBiTree;
    331     EnterLinkQueue(&tLinkQueue,tQueueElement);
    332     while(0!=IsLinkQueueEmpty(&tLinkQueue))
    333     {
    334         ExitLinkQueue(&tLinkQueue,&tQueueElement);
    335         printf("%c ",tQueueElement.ptData->cData);
    336         ptBiTreeNode=tQueueElement.ptData;
    337         if(NULL==ptBiTreeNode->ptLeftChild)
    338         {
    339         }
    340         else
    341         {
    342             tQueueElement.ptData=ptBiTreeNode->ptLeftChild;
    343             EnterLinkQueue(&tLinkQueue,tQueueElement);
    344         }
    345         if(NULL==ptBiTreeNode->ptRightChild)
    346         {
    347         }
    348         else
    349         {
    350             tQueueElement.ptData=ptBiTreeNode->ptRightChild;
    351             EnterLinkQueue(&tLinkQueue,tQueueElement);//左右孩子入队后,如果该结点还有兄弟没处理,
    352         }//接下来处理的就是之前入队的兄弟结点
    353     }
    354     printf("
    ");
    355 }
    356 /*****************************************************************************
    357 -Fuction        : UseStackInOrderTraverseLinkBiTree
    358 -Description    : // 中序遍历二叉树T的非递归算法(利用栈),
    359 -Input            : 
    360 -Output         : 
    361 -Return         : 
    362 * Modify Date      Version         Author           Modification
    363 * -----------------------------------------------
    364 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    365 ******************************************************************************/
    366 static void UseStackInOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree)
    367 {
    368     T_SeqStack tSeqStack={0};
    369     T_StackElement tStackElement={0};
    370     InitSeqStack(&tSeqStack);
    371     tStackElement.ptData=i_ptLinkBiTree;
    372     while(NULL!=tStackElement.ptData||0!=IsSeqStackEmpty(&tSeqStack))
    373     {
    374         if(NULL!=tStackElement.ptData)//指针不为空一直入栈
    375         {
    376             PushSeqStack(&tSeqStack,&tStackElement);
    377             tStackElement.ptData=tStackElement.ptData->ptLeftChild;//先放左子树
    378         }
    379         else
    380         {//当左子树为空则出栈为左子树的父结点
    381             PopSeqStack(&tSeqStack,&tStackElement);//当为右孩子为空则出栈为根结点
    382             printf("%c ",tStackElement.ptData->cData);
    383         //当左子树时,右孩子为空不会被入栈
    384             tStackElement.ptData=tStackElement.ptData->ptRightChild;//当为根结点时右孩子入栈
    385         }
    386     }
    387     printf("
    ");
    388 }
    389 /*****************************************************************************
    390 -Fuction        : OptimizeUseStackInOrderTraverseLinkBiTree
    391 -Description    : 先PUSH
    392 // 中序遍历二叉树T的非递归算法(利用栈),
    393 -Input            : 
    394 -Output         : 
    395 -Return         : 
    396 * Modify Date      Version         Author           Modification
    397 * -----------------------------------------------
    398 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    399 ******************************************************************************/
    400 static void OptimizeUseStackInOrderTraverseLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTree)
    401 {
    402     T_SeqStack tSeqStack={0};
    403     T_StackElement tStackElement={0};
    404     InitSeqStack(&tSeqStack);
    405     tStackElement.ptData=i_ptLinkBiTree;
    406     PushSeqStack(&tSeqStack,&tStackElement);//先PUSH
    407     while(0!=IsSeqStackEmpty(&tSeqStack))
    408     {
    409         while(0==GetSeqStackTopElement(&tSeqStack,&tStackElement)&&NULL!=tStackElement.ptData)
    410         {
    411             tStackElement.ptData=tStackElement.ptData->ptLeftChild;// 向左走到尽头,左优先
    412             PushSeqStack(&tSeqStack,&tStackElement);
    413         }
    414         PopSeqStack(&tSeqStack,&tStackElement);// 空指针退栈
    415         if(0!=IsSeqStackEmpty(&tSeqStack))// 访问结点,向右一步
    416         {//由于前面空指针退栈,再次出栈就是左孩子了
    417             PopSeqStack(&tSeqStack,&tStackElement);//当为右孩子为空前面有空出栈,
    418             printf("%c ",tStackElement.ptData->cData);//所以出栈为根结点
    419         //当左子树时,右孩子为空前面会出栈
    420             tStackElement.ptData=tStackElement.ptData->ptRightChild;//当为根结点时右孩子入栈
    421             PushSeqStack(&tSeqStack,&tStackElement);//当右孩子子树为空则访问右孩子,实现中序遍历
    422         }
    423         else
    424         {
    425         }
    426     }
    427     printf("
    ");
    428 }
    429 
    430 /*****************************************************************************
    431 -Fuction        : IsLinkBiTreeEmpty
    432 -Description    : IsLinkBiTreeEmpty
    433 -Input            : 
    434 -Output         : 
    435 -Return         : 
    436 * Modify Date      Version         Author           Modification
    437 * -----------------------------------------------
    438 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    439 ******************************************************************************/
    440 static int IsLinkBiTreeEmpty(T_LinkBiTreeNode *i_ptLinkBiTree)
    441 {
    442     int iRet=0;
    443     if(NULL==i_ptLinkBiTree)
    444     {
    445     }
    446     else
    447     {
    448         iRet=-1;
    449     }
    450     return iRet;
    451 }
    452 /*****************************************************************************
    453 -Fuction        : GetLinkBiTreeDepth
    454 -Description    : GetLinkBiTreeDepth
    455 -Input            : 
    456 -Output         : 
    457 -Return         : 
    458 * Modify Date      Version         Author           Modification
    459 * -----------------------------------------------
    460 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    461 ******************************************************************************/
    462 static int GetLinkBiTreeDepth(T_LinkBiTreeNode *i_ptLinkBiTree)
    463 {
    464     int iTreeDepth=0;
    465     int iLeftTreeDepth=0,iRightTreeDepth=0;
    466     if(NULL==i_ptLinkBiTree)
    467     {
    468         iTreeDepth=0;// 空树深度为0
    469     }
    470     else
    471     {
    472         if(NULL==i_ptLinkBiTree->ptLeftChild)
    473         {
    474             iLeftTreeDepth=0;//就一个时就本身时,深度为1,后面就会要加一
    475         }
    476         else
    477         {
    478             iLeftTreeDepth=GetLinkBiTreeDepth(i_ptLinkBiTree->ptLeftChild);// 为左子树的深度
    479         }//求得子树的深度,需要加上本身的深度,所以后面也会要加一
    480         if(NULL==i_ptLinkBiTree->ptRightChild)
    481         {
    482             iRightTreeDepth=0;
    483         }
    484         else
    485         {
    486             iRightTreeDepth=GetLinkBiTreeDepth(i_ptLinkBiTree->ptRightChild);// 为右子树的深度
    487         }
    488         iTreeDepth=iLeftTreeDepth>iRightTreeDepth?iLeftTreeDepth+1:iRightTreeDepth+1;
    489         // T的深度为其左右子树的深度中的大者+1
    490     }
    491 
    492     return iTreeDepth;
    493 }
    494 /*****************************************************************************
    495 -Fuction        : GetLinkBiTreeRootData
    496 -Description    : GetLinkBiTreeRootData
    497 -Input            : 
    498 -Output         : 
    499 -Return         : 
    500 * Modify Date      Version         Author           Modification
    501 * -----------------------------------------------
    502 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    503 ******************************************************************************/
    504 static char GetLinkBiTreeRootData(T_LinkBiTreeNode *i_ptLinkBiTree)
    505 {
    506     char cData;
    507     if(0==IsLinkBiTreeEmpty(i_ptLinkBiTree))
    508     {
    509         cData=NIL;
    510     }
    511     else
    512     {
    513         cData=i_ptLinkBiTree->cData;
    514     }
    515     return cData;
    516 }
    517 /*****************************************************************************
    518 -Fuction        : GetLinkBiTreeNodeData
    519 -Description    : GetLinkBiTreeNodeData
    520 -Input            : 
    521 -Output         : 
    522 -Return         : 
    523 * Modify Date      Version         Author           Modification
    524 * -----------------------------------------------
    525 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    526 ******************************************************************************/
    527 static char GetLinkBiTreeNodeData(T_LinkBiTreeNode *i_ptLinkBiTreeNode)
    528 {
    529     return i_ptLinkBiTreeNode->cData;
    530 }
    531 /*****************************************************************************
    532 -Fuction        : AssignToLinkBiTreeNode
    533 -Description    : AssignToLinkBiTreeNode
    534 -Input            : 
    535 -Output         : 
    536 -Return         : 
    537 * Modify Date      Version         Author           Modification
    538 * -----------------------------------------------
    539 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    540 ******************************************************************************/
    541 static void AssignToLinkBiTreeNode(T_LinkBiTreeNode *i_ptLinkBiTreeNode,char i_cData)
    542 {
    543     i_ptLinkBiTreeNode->cData=i_cData;
    544 }
    545 /*****************************************************************************
    546 -Fuction        : GetLinkBiTreeNodePoint
    547 -Description    : // 返回二叉树T中指向元素值为s的结点的指针
    548 -Input            : 
    549 -Output         : 
    550 -Return         : 
    551 * Modify Date      Version         Author           Modification
    552 * -----------------------------------------------
    553 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    554 ******************************************************************************/
    555 static T_LinkBiTreeNode *GetLinkBiTreeNodePoint(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData)
    556 {
    557     T_LinkQueue tLinkQueue={0};
    558     T_QueueDataElement tExitQueueElement={0};
    559     T_QueueDataElement tEnterQueueElement={0};
    560     T_LinkBiTreeNode *ptLinkBiTreeNode=NULL;
    561     if(NULL==i_ptLinkBiTree)// 非空树
    562     {
    563     }
    564     else
    565     {
    566         InitLinkQueue(&tLinkQueue);
    567         tEnterQueueElement.ptData=i_ptLinkBiTree;
    568         EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 根指针入队
    569         while(0!=IsLinkQueueEmpty(&tLinkQueue))// 队不空// 出队
    570         {
    571             ExitLinkQueue(&tLinkQueue,&tExitQueueElement);
    572             //printf("EnterData:%c
    ",tExitQueueElement.ptData->cData);
    573             if(i_cData==tExitQueueElement.ptData->cData)
    574             {
    575                 ptLinkBiTreeNode=tExitQueueElement.ptData;
    576                 break;
    577             }
    578             else
    579             {
    580                 if(NULL==tExitQueueElement.ptData->ptLeftChild)
    581                 {
    582                 }
    583                 else
    584                 {
    585                     tEnterQueueElement.ptData=tExitQueueElement.ptData->ptLeftChild;
    586                     EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 入队左孩子
    587                     //printf("1EnterLinkQueue:%c
    ",tEnterQueueElement.ptData->cData);
    588                 }
    589                 if(NULL==tExitQueueElement.ptData->ptRightChild)
    590                 {
    591                 }
    592                 else
    593                 {
    594                     tEnterQueueElement.ptData=tExitQueueElement.ptData->ptRightChild;
    595                     EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 入队右孩子
    596                     //printf("2EnterLinkQueue:%c
    ",tEnterQueueElement.ptData->cData);
    597                 }
    598             }
    599         }
    600     }
    601     return ptLinkBiTreeNode;
    602 }
    603 /*****************************************************************************
    604 -Fuction        : GetLinkBiTreeNodeParentData
    605 -Description    : 
    606 // 操作结果:若i_cData是T的非根结点,则返回它的双亲,否则返回“空”
    607 -Input            : 
    608 -Output         : 
    609 -Return         : 
    610 * Modify Date      Version         Author           Modification
    611 * -----------------------------------------------
    612 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    613 ******************************************************************************/
    614 static char GetLinkBiTreeParentData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData)
    615 {
    616     T_LinkQueue tLinkQueue={0};
    617     T_QueueDataElement tExitQueueElement;
    618     T_QueueDataElement tEnterQueueElement;
    619     char  cData=NIL;
    620     if(NULL==i_ptLinkBiTree)
    621     {
    622     }
    623     else
    624     {
    625         InitLinkQueue(&tLinkQueue);
    626         tEnterQueueElement.ptData=i_ptLinkBiTree;
    627         EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 根指针入队
    628         while(0!=IsLinkQueueEmpty(&tLinkQueue))// 队不空// 出队
    629         {
    630             ExitLinkQueue(&tLinkQueue,&tExitQueueElement);
    631             //printf("EnterParentData:%c
    ",tExitQueueElement.ptData->cData);
    632             if(((NULL!=tExitQueueElement.ptData->ptLeftChild)&&(i_cData==tExitQueueElement.ptData->ptLeftChild->cData)) ||
    633                 ((NULL!=tExitQueueElement.ptData->ptRightChild)&&(i_cData==tExitQueueElement.ptData->ptRightChild->cData)))
    634             {
    635                 cData=tExitQueueElement.ptData->cData;
    636                 break;
    637             }
    638             else
    639             {
    640                 if(NULL==tExitQueueElement.ptData->ptLeftChild)
    641                 {
    642                 }
    643                 else
    644                 {
    645                     tEnterQueueElement.ptData=tExitQueueElement.ptData->ptLeftChild;
    646                     EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 入队左孩子
    647                 }
    648                 if(NULL==tExitQueueElement.ptData->ptRightChild)
    649                 {
    650                 }
    651                 else
    652                 {
    653                     tEnterQueueElement.ptData=tExitQueueElement.ptData->ptRightChild;
    654                     EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 入队右孩子
    655                 }
    656             }
    657         }
    658     }
    659     return cData;
    660 }
    661 /*****************************************************************************
    662 -Fuction        : GetLinkBiTreeLeftChildData
    663 -Description    : 
    664 // 初始条件:二叉树存在,i_cData是树中某个结点数据。
    665 操作结果:返回i_cData的左孩子。若i_cData无左孩子,则返回“空”
    666 -Input            : 
    667 -Output         : 
    668 -Return         : 
    669 * Modify Date      Version         Author           Modification
    670 * -----------------------------------------------
    671 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    672 ******************************************************************************/
    673 static char GetLinkBiTreeLeftChildData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData)
    674 {
    675     T_LinkBiTreeNode *ptBiTreeNode=NULL;
    676     char  cData=NIL;
    677     if(NULL==i_ptLinkBiTree)
    678     {
    679     }
    680     else
    681     {
    682         ptBiTreeNode=GetLinkBiTreeNodePoint(i_ptLinkBiTree,i_cData);
    683         if(NULL!=ptBiTreeNode&&NULL!=ptBiTreeNode->ptLeftChild)
    684         {
    685             cData=ptBiTreeNode->ptLeftChild->cData;
    686         }
    687         else{
    688         }
    689     }
    690     return cData;
    691 }
    692 /*****************************************************************************
    693 -Fuction        : GetLinkBiTreeRightChildData
    694 -Description    : 
    695 // 初始条件:二叉树存在,i_cData是树中某个结点数据。
    696 操作结果:返回i_cData的左孩子。若i_cData无左孩子,则返回“空”
    697 -Input            : 
    698 -Output         : 
    699 -Return         : 
    700 * Modify Date      Version         Author           Modification
    701 * -----------------------------------------------
    702 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    703 ******************************************************************************/
    704 static char GetLinkBiTreeRightChildData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData)
    705 {
    706     T_LinkBiTreeNode *ptBiTreeNode=NULL;
    707     char  cData=NIL;
    708     if(NULL==i_ptLinkBiTree)
    709     {
    710     }
    711     else
    712     {
    713         ptBiTreeNode=GetLinkBiTreeNodePoint(i_ptLinkBiTree,i_cData);
    714         if(NULL!=ptBiTreeNode&&NULL!=ptBiTreeNode->ptRightChild)
    715         {
    716             cData=ptBiTreeNode->ptRightChild->cData;
    717         }
    718         else{
    719         }
    720     }
    721     return cData;
    722 }
    723 /*****************************************************************************
    724 -Fuction        : GetLinkBiTreeLeftSiblingData
    725 -Description    : 
    726 // 初始条件:二叉树存在,i_cData是树中某个结点数据。
    727 操作结果:返回i_cData的左孩子。若i_cData无左孩子,则返回“空”
    728 -Input            : 
    729 -Output         : 
    730 -Return         : 
    731 * Modify Date      Version         Author           Modification
    732 * -----------------------------------------------
    733 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    734 ******************************************************************************/
    735 static char GetLinkBiTreeLeftSiblingData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData)
    736 {
    737     T_LinkBiTreeNode *ptBiTreeNode=NULL;
    738     char cParentData=NIL;
    739     char  cData=NIL;
    740     if(NULL==i_ptLinkBiTree)
    741     {
    742     }
    743     else
    744     {
    745         cParentData=GetLinkBiTreeParentData(i_ptLinkBiTree,i_cData);
    746         if(NIL==cParentData)
    747         {
    748         }
    749         else
    750         {
    751             ptBiTreeNode=GetLinkBiTreeNodePoint(i_ptLinkBiTree,cParentData);
    752             if(NULL!=ptBiTreeNode&&NULL!=ptBiTreeNode->ptLeftChild
    753                 &&NULL!=ptBiTreeNode->ptRightChild &&i_cData==ptBiTreeNode->ptRightChild->cData)
    754             {
    755                 cData=ptBiTreeNode->ptLeftChild->cData;
    756             }
    757             else{
    758             }
    759         }
    760     }
    761     return cData;
    762 }
    763 /*****************************************************************************
    764 -Fuction        : GetLinkBiTreeRightSiblingData
    765 -Description    : 
    766 // 初始条件:二叉树存在,i_cData是树中某个结点数据。
    767 操作结果:返回i_cData的左孩子。若i_cData无左孩子,则返回“空”
    768 -Input            : 
    769 -Output         : 
    770 -Return         : 
    771 * Modify Date      Version         Author           Modification
    772 * -----------------------------------------------
    773 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    774 ******************************************************************************/
    775 static char GetLinkBiTreeRightSiblingData(T_LinkBiTreeNode *i_ptLinkBiTree,char i_cData)
    776 {
    777     T_LinkBiTreeNode *ptBiTreeNode=NULL;
    778     char cParentData=NIL;
    779     char  cData=NIL;
    780     if(NULL==i_ptLinkBiTree)
    781     {
    782     }
    783     else
    784     {
    785         cParentData=GetLinkBiTreeParentData(i_ptLinkBiTree,i_cData);
    786         if(NIL==cParentData)
    787         {
    788         }
    789         else
    790         {
    791             ptBiTreeNode=GetLinkBiTreeNodePoint(i_ptLinkBiTree,cParentData);
    792             if(NULL!=ptBiTreeNode&&NULL!=ptBiTreeNode->ptLeftChild
    793                 &&NULL!=ptBiTreeNode->ptRightChild &&i_cData==ptBiTreeNode->ptLeftChild->cData)
    794             {
    795                 cData=ptBiTreeNode->ptRightChild->cData;
    796             }
    797             else{
    798             }
    799         }
    800     }
    801     return cData;
    802 }
    803 /*****************************************************************************
    804 -Fuction        : InsertChildInLinkBiTree
    805 -Description    : 
    806 // 初始条件:二叉树T存在,i_ptLinkBiTreeNode指向T中某个结点,
    807 i_iLeftOrRight为0或1,非空二叉树i_ptInsertLinkBiTree与T不相交且右子树为空
    808 // 操作结果:根据i_iLeftOrRight为0或1,插入i_ptInsertLinkBiTree为T中
    809 i_ptLinkBiTreeNode所指结点的左或右子树。i_ptLinkBiTreeNode所指结点的
    810 // 原有左或右子树则成为i_ptInsertLinkBiTree的右子树
    811 -Input            : 
    812 -Output         : 
    813 -Return         : -1 false         0 true
    814 * Modify Date      Version         Author           Modification
    815 * -----------------------------------------------
    816 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    817 ******************************************************************************/
    818 static int InsertChildInLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTreeNode,int i_iLeftOrRight,T_LinkBiTreeNode *i_ptInsertLinkBiTree)
    819 {
    820     int iRet=-1;
    821     if(NULL==i_ptLinkBiTreeNode)
    822     {
    823         iRet=-1;
    824     }
    825     else
    826     {
    827         iRet=0;
    828         if(0==i_iLeftOrRight)
    829         {
    830             i_ptInsertLinkBiTree->ptRightChild=i_ptLinkBiTreeNode->ptLeftChild;
    831             i_ptLinkBiTreeNode->ptLeftChild=i_ptInsertLinkBiTree;
    832         }
    833         else if(1==i_iLeftOrRight)
    834         {
    835             i_ptInsertLinkBiTree->ptRightChild=i_ptLinkBiTreeNode->ptRightChild;
    836             i_ptLinkBiTreeNode->ptRightChild=i_ptInsertLinkBiTree;
    837         }
    838         else
    839         {
    840             printf("UnknowChild:%d,InsertChildInLinkBiTree err
    ",i_iLeftOrRight);
    841             iRet=-1;
    842         }
    843     }
    844     return iRet;
    845 }
    846 /*****************************************************************************
    847 -Fuction        : InsertChildInLinkBiTree
    848 -Description    : 
    849 // 初始条件:二叉树T存在,i_ptLinkBiTreeNode指向T中某个结点,i_iLeftOrRight为0或1
    850 // 操作结果:根据i_iLeftOrRight为0或1,删除T中i_ptLinkBiTreeNode所指结点的左或右子树
    851 -Input            : 
    852 -Output         : 
    853 -Return         : -1 false         0 true
    854 * Modify Date      Version         Author           Modification
    855 * -----------------------------------------------
    856 * 2017/05/15      V1.0.0         Yu Weifeng       Created
    857 ******************************************************************************/
    858 static int DeleteChildInLinkBiTree(T_LinkBiTreeNode *i_ptLinkBiTreeNode,int i_iLeftOrRight)
    859 {
    860     int iRet=-1;
    861     if(NULL==i_ptLinkBiTreeNode)
    862     {
    863         iRet=-1;
    864     }
    865     else
    866     {
    867         iRet=0;
    868         if(0==i_iLeftOrRight)
    869         {
    870             ClearLinkBiTree(i_ptLinkBiTreeNode->ptLeftChild);
    871         }
    872         else if(1==i_iLeftOrRight)
    873         {
    874             ClearLinkBiTree(i_ptLinkBiTreeNode->ptRightChild);
    875         }
    876         else
    877         {
    878             printf("UnknowChild:%d,DeleteChildInLinkBiTree err
    ",i_iLeftOrRight);
    879             iRet=-1;
    880         }
    881     }
    882     return iRet;
    883 }
    LinkBiTree.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     LinkBiTree.h
     5 * Description        :     LinkBiTree operation center
     6 * Created            :     2017.05.17.
     7 * Author            :     Yu Weifeng
     8 * Function List         :     
     9 * Last Modified     :     
    10 * History            :     
    11 ******************************************************************************/
    12 #ifndef _LINK_BI_TREE_H
    13 #define _LINK_BI_TREE_H
    14 
    15 typedef struct LinkBiTreeNode
    16 {
    17     char cData;
    18     struct LinkBiTreeNode *ptLeftChild,*ptRightChild;
    19 }T_LinkBiTreeNode,*PT_LinkBiTreeNode;
    20 
    21 
    22 
    23 
    24 #endif
    LinkBiTree.h

    2)顺序二叉树

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     SeqBiTree.c
      5 * Description        :     SeqBiTree operation center
      6 * Created            :     2017.05.08.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include "stdio.h"
     13 #include "malloc.h"
     14 #include "stdlib.h"
     15 #include "string.h"
     16 #include "math.h"
     17 #include "LinkQueue.c"
     18 
     19 typedef struct SeqBiTreeElement
     20 {
     21     //char cData;//NULL表示空元素也就是空结点
     22     int iData;//0表示空元素也就是空结点
     23 }T_SeqBiTreeElement,*PT_SeqBiTreeElement;
     24 
     25 typedef struct PositionInTree
     26 {
     27     int iLevel;//元素处在的层次 从1开始
     28     int iOrder;//元素在本层中的序号  从1开始
     29 }T_PositionInTree,*PT_PositionInTree;
     30 
     31 #define MAX_SEQ_BINARY_TREE_LEN    100
     32 
     33 static void InitSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     34 static void CreateSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     35 static void LevelOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     36 static void PreOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     37 static void InOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     38 static void PostOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     39 static T_SeqBiTreeElement GetSeqBiTreeElement(T_SeqBiTreeElement *i_ptSeqBiTree,T_PositionInTree *i_ptPos);
     40 static int AssignToSeqBiTreeElement(T_SeqBiTreeElement *i_ptSeqBiTree,T_PositionInTree *i_ptPos,T_SeqBiTreeElement *i_ptValue);
     41 static void PreOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     42 
     43 static T_SeqBiTreeElement GetParentFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement);
     44 static T_SeqBiTreeElement GetLeftChildFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement);
     45 static T_SeqBiTreeElement GetRightChildFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement);
     46 static T_SeqBiTreeElement GetLeftSiblingFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement);
     47 static T_SeqBiTreeElement GetRightSiblingFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement);
     48 
     49 static void PrintfSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree);
     50 static void InsertChildInSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptInsertNode,int i_iLeftOrRight,T_SeqBiTreeElement *i_ptInsertTree);
     51 static int DeleteChildInSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_PositionInTree*i_ptDeleteNodePos,int i_iLeftOrRight);
     52 
     53 #define ClearSeqBiTree     InitSeqBiTree     // 在顺序存储结构中,两函数完全一样
     54 #define DestroySeqBiTree     InitSeqBiTree         // 在顺序存储结构中,两函数完全一样
     55 #define NIL 0
     56 static int IsSeqBiTreeEmpty(T_SeqBiTreeElement *i_ptSeqBiTree);
     57 static int GetSeqBiTreeDepth(T_SeqBiTreeElement *i_ptSeqBiTree);
     58 /*****************************************************************************
     59 -Fuction        : main
     60 -Description    : main
     61 -Input            : 
     62 -Output         : 
     63 -Return         : 
     64 * Modify Date      Version         Author           Modification
     65 * -----------------------------------------------
     66 * 2017/05/08      V1.0.0         Yu Weifeng       Created
     67 ******************************************************************************/
     68 int main(int argc,char **argv)
     69 {
     70     T_SeqBiTreeElement atSeqBiTree[MAX_SEQ_BINARY_TREE_LEN]={0};
     71     T_SeqBiTreeElement atSeqBiTreeRightTreeNull[MAX_SEQ_BINARY_TREE_LEN]={0};
     72     T_PositionInTree tPos={0};
     73     T_SeqBiTreeElement tElement={0};
     74     T_SeqBiTreeElement tOtherElement={0};
     75     int iLeftOrRight;
     76     
     77     CreateSeqBiTree(atSeqBiTree);
     78     printf("建立二叉树后,树空否?%d(1:是0:否) 树的深度=%d
    ",IsSeqBiTreeEmpty(atSeqBiTree),GetSeqBiTreeDepth(atSeqBiTree));
     79     printf("层序遍历二叉树:");
     80     LevelOrderTraverseSeqBiTree(atSeqBiTree);
     81     printf("中序遍历二叉树:");
     82     InOrderTraverseSeqBiTree(atSeqBiTree);
     83     printf("后序遍历二叉树:");
     84     PostOrderTraverseSeqBiTree(atSeqBiTree);
     85     
     86     printf("请输入待修改结点的层号,本层序号:");
     87     scanf("%d,%d",&tPos.iLevel,&tPos.iOrder);
     88     tElement=GetSeqBiTreeElement(atSeqBiTree,&tPos);
     89     printf("待修改结点的原值为%d,请输入新值:",tElement.iData);
     90     scanf("%d",&tElement.iData);
     91     AssignToSeqBiTreeElement(atSeqBiTree,&tPos,&tElement);
     92     printf("先序遍历二叉树:");
     93     PreOrderTraverseSeqBiTree(atSeqBiTree);
     94 
     95     tOtherElement=GetParentFromSeqBiTree(atSeqBiTree,&tElement);
     96     printf("结点%d的双亲为%d
    ",tElement.iData,tOtherElement.iData);
     97     tOtherElement=GetLeftChildFromSeqBiTree(atSeqBiTree,&tElement);
     98     printf("结点%d的左孩子为%d
    ",tElement.iData,tOtherElement.iData);
     99     tOtherElement=GetRightChildFromSeqBiTree(atSeqBiTree,&tElement);
    100     printf("结点%d的右孩子为%d
    ",tElement.iData,tOtherElement.iData);
    101     tOtherElement=GetLeftSiblingFromSeqBiTree(atSeqBiTree,&tElement);
    102     printf("结点%d的左兄弟为%d
    ",tElement.iData,tOtherElement.iData);
    103     tOtherElement=GetRightSiblingFromSeqBiTree(atSeqBiTree,&tElement);
    104     printf("结点%d的右兄弟为%d
    ",tElement.iData,tOtherElement.iData);
    105     
    106     printf("建立右子树为空的树s:");
    107     CreateSeqBiTree(atSeqBiTreeRightTreeNull);
    108     printf("层序遍历二叉树:");
    109     LevelOrderTraverseSeqBiTree(atSeqBiTreeRightTreeNull);
    110     printf("树s插到树T中,请输入树T中树s的双亲结点,s为左(0)或右(1)子树:");
    111     scanf("%d,%d",&tElement.iData,&iLeftOrRight);
    112     InsertChildInSeqBiTree(atSeqBiTree,&tElement,iLeftOrRight,atSeqBiTreeRightTreeNull);
    113     PrintfSeqBiTree(atSeqBiTree);
    114     printf("删除子树,请输入待删除子树根结点的层号,本层序号,左(0)或右(1)子树:");
    115     scanf("%d,%d,%d",&tPos.iLevel,&tPos.iOrder,&iLeftOrRight);
    116     DeleteChildInSeqBiTree(atSeqBiTree,&tPos,iLeftOrRight);
    117     PrintfSeqBiTree(atSeqBiTree);
    118 
    119     ClearSeqBiTree(atSeqBiTree);
    120     printf("清除二叉树后,树空否?%d(1:是0:否) 树的深度=%d
    ",IsSeqBiTreeEmpty(atSeqBiTree),GetSeqBiTreeDepth(atSeqBiTree));
    121     
    122     return 0;
    123 }
    124 /*****************************************************************************
    125 -Fuction        : InitSeqBiTree
    126 -Description    : InitSeqBiTree
    127 -Input            : 
    128 -Output         : 
    129 -Return         : 
    130 * Modify Date      Version         Author           Modification
    131 * -----------------------------------------------
    132 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    133 ******************************************************************************/
    134 static void InitSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree)
    135 {
    136     int i;
    137     for(i=0;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    138     {
    139         i_ptSeqBiTree[i].iData=0;//初始化,没有元素为0
    140     }
    141 
    142 }
    143 /*****************************************************************************
    144 -Fuction        : CreateSeqBiTree
    145 -Description    : CreateSeqBiTree
    146 -Input            : 
    147 -Output         : 
    148 -Return         : 
    149 * Modify Date      Version         Author           Modification
    150 * -----------------------------------------------
    151 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    152 ******************************************************************************/
    153 static void CreateSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree)
    154 {
    155     int i;
    156     int iData=0;
    157     char acBiTreeElement[MAX_SEQ_BINARY_TREE_LEN]={0};
    158     InitSeqBiTree(i_ptSeqBiTree);
    159     /*printf("请按层序输入结点的值(字符),空格表示空结点,结点数:%d
    ",MAX_SEQ_BINARY_TREE_LEN);
    160     for(i=0;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    161     {
    162         iData=getchar();
    163         if(iData==EOF)
    164         {
    165             break;
    166         }
    167         else
    168         {
    169             i_ptSeqBiTree[i].cData=(char)iData;
    170         }
    171     }*/
    172     printf("请按层序输入结点的值(整型),0表示空结点,输999结束。结点数:%d
    ",MAX_SEQ_BINARY_TREE_LEN);
    173     for(i=0;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    174     {
    175         scanf("%d",&iData);
    176         if(iData==999)
    177         {
    178             i_ptSeqBiTree[i].iData=0;
    179             break;
    180         }
    181         else
    182         {
    183             i_ptSeqBiTree[i].iData=iData;
    184         }
    185     }
    186     for(i=1;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    187     {
    188         if((i!=0)&&(i_ptSeqBiTree[i].iData!=0)&&(i_ptSeqBiTree[(i+1)/2-1].iData==0))
    189         {
    190             printf("出现结点(不空)无双亲且不是根,程序退出
    ");
    191             exit(-1);
    192         }
    193         else
    194         {
    195         }
    196     }
    197 }
    198 /*****************************************************************************
    199 -Fuction        : InitSeqBiTree
    200 -Description    : InitSeqBiTree
    201 -Input            : 
    202 -Output         : 1代表空
    203 -Return         : 
    204 * Modify Date      Version         Author           Modification
    205 * -----------------------------------------------
    206 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    207 ******************************************************************************/
    208 static int IsSeqBiTreeEmpty(T_SeqBiTreeElement *i_ptSeqBiTree)
    209 {
    210     int iRet=0;
    211     if(i_ptSeqBiTree[0].iData!=0)
    212     {
    213         iRet=0;
    214     }
    215     else
    216     {
    217         iRet=1;
    218     }
    219     return iRet;
    220 }
    221 /*****************************************************************************
    222 -Fuction        : GetSeqBiTreeDepth
    223 -Description    : GetSeqBiTreeDepth
    224 -Input            : 
    225 -Output         : 
    226 -Return         : 
    227 * Modify Date      Version         Author           Modification
    228 * -----------------------------------------------
    229 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    230 ******************************************************************************/
    231 static int GetSeqBiTreeDepth(T_SeqBiTreeElement *i_ptSeqBiTree)
    232 {
    233     int iDepth;
    234     int i,j;
    235     for(i=MAX_SEQ_BINARY_TREE_LEN-1;i>=0;i--)//中间可能出现空节点
    236     {
    237         if(i_ptSeqBiTree[i].iData==0)
    238         {
    239         }
    240         else
    241         {
    242             break;//指向最后一个非空结点为其序号
    243         }
    244     }
    245     i++;//树的长度,或者从1开始算的序号
    246     //这样算树每层第一个序号就是1,2,4,8,方便比较计算
    247     j=-1;//没有根节点,即结点为空时,深度为0,所以从-1开始
    248     do{
    249         j++;
    250     }while(i>=pow(2,j));
    251     return j;
    252 }
    253 /*****************************************************************************
    254 -Fuction        : GetSeqBiTreeElement
    255 -Description    : GetSeqBiTreeElement
    256 -Input            : 
    257 -Output         : 
    258 -Return         : 
    259 * Modify Date      Version         Author           Modification
    260 * -----------------------------------------------
    261 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    262 ******************************************************************************/
    263 static T_SeqBiTreeElement GetSeqBiTreeElement(T_SeqBiTreeElement *i_ptSeqBiTree,T_PositionInTree *i_ptPos)
    264 {
    265     T_SeqBiTreeElement tTreeElement={0};
    266     tTreeElement=i_ptSeqBiTree[(int)(pow(2,i_ptPos->iLevel-1)+i_ptPos->iOrder-2)];
    267     return tTreeElement;
    268 }
    269 /*****************************************************************************
    270 -Fuction        : AssignToSeqBiTreeElement
    271 -Description    :
    272 // 操作结果:给处于位置e(层,本层序号)的结点赋新值value
    273 -Input            : 
    274 -Output         : 
    275 -Return         : 
    276 * Modify Date      Version         Author           Modification
    277 * -----------------------------------------------
    278 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    279 ******************************************************************************/
    280 static int AssignToSeqBiTreeElement(T_SeqBiTreeElement *i_ptSeqBiTree,T_PositionInTree *i_ptPos,T_SeqBiTreeElement *i_ptValue)
    281 {
    282     int iRet=0;
    283     int i=0;
    284     i=(int)(pow(2,i_ptPos->iLevel-1)+i_ptPos->iOrder-2);// 将层、本层序号转为数组的序号
    285     if((i_ptValue->iData!=0)&&(i_ptSeqBiTree[(i+1)/2-1].iData==0))// 给叶子赋非空值但双亲为空
    286     {
    287         iRet=-1;
    288         printf("DataNull,ButElementParentNull err
    ");
    289     }
    290     else if((i_ptValue->iData==0)&&((i_ptSeqBiTree[2*i+1].iData!=0)||(i_ptSeqBiTree[2*i+2].iData!=0)))// 给双亲赋空值但有叶子(不空)
    291     {
    292         iRet=-1;
    293         printf("DataNull,ButHaveChildNotNull err
    ");
    294     }
    295     else
    296     {
    297         memcpy(&i_ptSeqBiTree[i],i_ptValue,sizeof(T_SeqBiTreeElement));
    298         iRet=0;
    299     }
    300     return iRet;
    301 }
    302 /*****************************************************************************
    303 -Fuction        : GetParentFromSeqBiTree
    304 -Description    :
    305 // 操作结果:若e是T的非根结点,则返回它的双亲;否则返回“空”
    306 -Input            : 
    307 -Output         : 
    308 -Return         : 
    309 * Modify Date      Version         Author           Modification
    310 * -----------------------------------------------
    311 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    312 ******************************************************************************/
    313 static T_SeqBiTreeElement GetParentFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement)
    314 {
    315     T_SeqBiTreeElement tSeqBiTreeElement={0};
    316     tSeqBiTreeElement.iData=0;
    317     int i=0;
    318     if(i_ptSeqBiTree[0].iData==0)// 空树
    319     {
    320     }
    321     else
    322     {
    323         for(i=1;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    324         {
    325             if(i_ptSeqBiTree[i].iData==i_ptTreeElement->iData)// 找到
    326             {
    327                 memcpy(&tSeqBiTreeElement,&i_ptSeqBiTree[(i+1)/2-1],sizeof(T_SeqBiTreeElement));
    328             }
    329             else
    330             {
    331             }
    332         }
    333     }
    334     return tSeqBiTreeElement;
    335 }
    336 /*****************************************************************************
    337 -Fuction        : GetLeftChildFromSeqBiTree
    338 -Description    :
    339 -Input            : 
    340 -Output         : 
    341 -Return         : 
    342 * Modify Date      Version         Author           Modification
    343 * -----------------------------------------------
    344 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    345 ******************************************************************************/
    346 static T_SeqBiTreeElement GetLeftChildFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement)
    347 {
    348     T_SeqBiTreeElement tSeqBiTreeElement={0};
    349     tSeqBiTreeElement.iData=0;
    350     int i=0;
    351     if(i_ptSeqBiTree[0].iData==0)// 空树
    352     {
    353     }
    354     else
    355     {
    356         for(i=0;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    357         {
    358             if(i_ptSeqBiTree[i].iData==i_ptTreeElement->iData)// 找到
    359             {
    360                 memcpy(&tSeqBiTreeElement,&i_ptSeqBiTree[2*i+1],sizeof(T_SeqBiTreeElement));
    361             }
    362             else
    363             {
    364             }
    365         }
    366     }
    367     return tSeqBiTreeElement;
    368 }
    369 /*****************************************************************************
    370 -Fuction        : GetRightChildFromSeqBiTree
    371 -Description    :
    372 -Input            : 
    373 -Output         : 
    374 -Return         : 
    375 * Modify Date      Version         Author           Modification
    376 * -----------------------------------------------
    377 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    378 ******************************************************************************/
    379 static T_SeqBiTreeElement GetRightChildFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement)
    380 {
    381     T_SeqBiTreeElement tSeqBiTreeElement={0};
    382     tSeqBiTreeElement.iData=0;
    383     int i=0;
    384     if(i_ptSeqBiTree[0].iData==0)// 空树
    385     {
    386     }
    387     else
    388     {
    389         for(i=0;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    390         {
    391             if(i_ptSeqBiTree[i].iData==i_ptTreeElement->iData)// 找到
    392             {
    393                 memcpy(&tSeqBiTreeElement,&i_ptSeqBiTree[2*i+2],sizeof(T_SeqBiTreeElement));
    394             }
    395             else
    396             {
    397             }
    398         }
    399     }
    400     return tSeqBiTreeElement;
    401 }
    402 /*****************************************************************************
    403 -Fuction        : GetLeftSiblingFromSeqBiTree
    404 -Description    :
    405 // 操作结果:返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回“空”
    406 -Input            : 
    407 -Output         : 
    408 -Return         : 
    409 * Modify Date      Version         Author           Modification
    410 * -----------------------------------------------
    411 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    412 ******************************************************************************/
    413 static T_SeqBiTreeElement GetLeftSiblingFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement)
    414 {
    415     T_SeqBiTreeElement tSeqBiTreeElement={0};
    416     tSeqBiTreeElement.iData=0;
    417     int i=0;
    418     if(i_ptSeqBiTree[0].iData==0)// 空树
    419     {
    420     }
    421     else
    422     {
    423         for(i=0;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    424         {
    425             if((i_ptSeqBiTree[i].iData==i_ptTreeElement->iData)&&(i%2==0))
    426             {// 找到e且其序号为偶数(是右孩子)
    427                 memcpy(&tSeqBiTreeElement,&i_ptSeqBiTree[i-1],sizeof(T_SeqBiTreeElement));
    428             }
    429             else
    430             {
    431             }
    432         }
    433     }
    434     return tSeqBiTreeElement;
    435 }
    436 /*****************************************************************************
    437 -Fuction        : GetRightSiblingFromSeqBiTree
    438 -Description    :
    439 // 操作结果:返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回“空”
    440 -Input            : 
    441 -Output         : 
    442 -Return         : 
    443 * Modify Date      Version         Author           Modification
    444 * -----------------------------------------------
    445 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    446 ******************************************************************************/
    447 static T_SeqBiTreeElement GetRightSiblingFromSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptTreeElement)
    448 {
    449     T_SeqBiTreeElement tSeqBiTreeElement={0};
    450     tSeqBiTreeElement.iData=0;
    451     int i=0;
    452     if(i_ptSeqBiTree[0].iData==0)// 空树
    453     {
    454     }
    455     else
    456     {
    457         for(i=0;i<MAX_SEQ_BINARY_TREE_LEN;i++)
    458         {
    459             if((i_ptSeqBiTree[i].iData==i_ptTreeElement->iData)&&(i%2!=0))
    460             {// 找到e且其序号为奇数(是左孩子)
    461                 memcpy(&tSeqBiTreeElement,&i_ptSeqBiTree[i+1],sizeof(T_SeqBiTreeElement));
    462             }
    463             else
    464             {
    465             }
    466         }
    467     }
    468     return tSeqBiTreeElement;
    469 }
    470 /*****************************************************************************
    471 -Fuction        : MoveSeqBiTree
    472 -Description    :
    473 // 把从src的i_dwSrcPos结点开始的子树移为从dst的i_dwDstPos结点开始的子树
    474 -Input            : 
    475 -Output         : 
    476 -Return         : 
    477 * Modify Date      Version         Author           Modification
    478 * -----------------------------------------------
    479 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    480 ******************************************************************************/
    481 static void MoveSeqBiTree(T_SeqBiTreeElement *i_ptSrcSeqBiTree,int i_dwSrcPos,T_SeqBiTreeElement *i_ptDstSeqBiTree,int i_dwDstPos)
    482 {
    483     if(i_ptSrcSeqBiTree[2*i_dwSrcPos+1].iData!=0)// 把q的j结点的左子树移为T的i结点的左子树
    484     {
    485         MoveSeqBiTree(i_ptSrcSeqBiTree,2*i_dwSrcPos+1,i_ptDstSeqBiTree,2*i_dwDstPos+1);
    486     }
    487     else
    488     {
    489     }
    490     if(i_ptSrcSeqBiTree[2*i_dwSrcPos+2].iData!=0)// 把q的j结点的右子树移为T的i结点的右子树
    491     {
    492         MoveSeqBiTree(i_ptSrcSeqBiTree,2*i_dwSrcPos+2,i_ptDstSeqBiTree,2*i_dwDstPos+2);
    493     }
    494     else
    495     {
    496     }
    497     memcpy(&i_ptDstSeqBiTree[i_dwDstPos],&i_ptSrcSeqBiTree[i_dwSrcPos],sizeof(T_SeqBiTreeElement));
    498     i_ptSrcSeqBiTree[i_dwSrcPos].iData=0;
    499 }
    500 /*****************************************************************************
    501 -Fuction        : InsertChildInSeqBiTree
    502 -Description    :
    503 //操作结果:根据i_iLeftOrRight为0或1,插入i_ptInsertTree为i_ptSeqBiTree中
    504 i_ptInsertNode结点的左或右子树。
    505 i_ptInsertNode结点的原有左或右子树则成为i_ptInsertTree的右子树
    506 -Input            : 
    507 -Output         : 
    508 -Return         : 
    509 * Modify Date      Version         Author           Modification
    510 * -----------------------------------------------
    511 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    512 ******************************************************************************/
    513 static void InsertChildInSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_SeqBiTreeElement *i_ptInsertNode,int i_iLeftOrRight,T_SeqBiTreeElement *i_ptInsertTree)
    514 {
    515     int i;
    516     int i_dwInsertChildPos=0;
    517     for(i=0;i<(int)(pow(2,GetSeqBiTreeDepth(i_ptSeqBiTree)))-1;i++)// 查找i_ptInsertNode的序号
    518     {
    519         if(0==memcmp(&i_ptSeqBiTree[i],i_ptInsertNode,sizeof(T_SeqBiTreeElement)))
    520         {
    521             break;
    522         }
    523         else
    524         {
    525         }
    526     }
    527     i_dwInsertChildPos=2*i+1+i_iLeftOrRight;//i_dwInsertChildPos为i_ptInsertNode的左或右孩子的序号
    528     if(i_ptSeqBiTree[i_dwInsertChildPos].iData!=0)
    529     {// 把从i_ptSeqBiTree的i_dwInsertChildPos结点开始的子树移为从i_dwInsertChildPos结点的右子树开始的子树
    530         MoveSeqBiTree(i_ptSeqBiTree,i_dwInsertChildPos,i_ptSeqBiTree,2*i_dwInsertChildPos+2);
    531         //结点开始的子树移动到结点孩子开始的子树,递归导致先执行最后结点移动到
    532         //目标的空节点上,此时原来元素已经保存,就可以继续移动结点,类似于
    533         //数组元素整体后移
    534     }
    535     else
    536     {
    537     }
    538     MoveSeqBiTree(i_ptInsertTree,0,i_ptSeqBiTree,i_dwInsertChildPos);// 把从i_ptInsertTree的开始的子树移为从i_ptSeqBiTree的i_dwInsertChildPos结点开始的子树
    539 //由于前面的操作同时也导致了
    540 //i_ptInsertNode结点的原有左或右子树则成为i_ptInsertTree的右子树
    541 }
    542 /*****************************************************************************
    543 -Fuction        : DeleteChildInSeqBiTree
    544 -Description    :
    545 // 操作结果:根据LR为1或0,删除T中p所指结点的左或右子树
    546 -Input            : 
    547 -Output         : 
    548 -Return         : 
    549 * Modify Date      Version         Author           Modification
    550 * -----------------------------------------------
    551 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    552 ******************************************************************************/
    553 static int DeleteChildInSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,T_PositionInTree*i_ptDeleteNodePos,int i_iLeftOrRight)
    554 {
    555     int iRet=0;
    556     int i;
    557     T_LinkQueue tLinkQueue={0};
    558 
    559     InitLinkQueue(&tLinkQueue);
    560     // 将层、本层序号转为矩阵的序号
    561     i=(int)pow(2,i_ptDeleteNodePos->iLevel-1)+i_ptDeleteNodePos->iOrder-2;// 将层、本层序号转为矩阵的序号
    562     if(i_ptSeqBiTree[i].iData==0)// 此结点空
    563     {
    564         iRet=-1;
    565         printf("DeleteNodeIsNull,err
    ");
    566     }
    567     else
    568     {
    569         i=2*i+1+i_iLeftOrRight;// 待删除子树的根结点在矩阵中的序号
    570         //printf("DeleteNodePos:%d
    ",i);
    571         while(iRet==0)
    572         {
    573             if(i_ptSeqBiTree[2*i+1].iData!=0)
    574             {
    575                 EnterLinkQueue(&tLinkQueue,(char)(2*i+1));// 入队左结点的序号    
    576             }
    577             else{
    578             }
    579             if(i_ptSeqBiTree[2*i+2].iData!=0)
    580             {
    581                 EnterLinkQueue(&tLinkQueue,(char)(2*i+2));    
    582             }
    583             else{
    584             }
    585             i_ptSeqBiTree[i].iData=0;
    586             iRet=ExitLinkQueue(&tLinkQueue,(char *)&i);// 队列不空
    587         }
    588         
    589     }
    590     return iRet;
    591 }
    592 /*****************************************************************************
    593 -Fuction        : PreTraverseSeqBiTree
    594 -Description    :
    595 -Input            : 
    596 -Output         : 
    597 -Return         : 
    598 * Modify Date      Version         Author           Modification
    599 * -----------------------------------------------
    600 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    601 ******************************************************************************/
    602 static void PreTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,int i_dwPos)
    603 {
    604     printf("%d ",i_ptSeqBiTree[i_dwPos].iData);
    605     if(i_ptSeqBiTree[i_dwPos*2+1].iData!=0)// 左子树不空
    606     {
    607         PreTraverseSeqBiTree(i_ptSeqBiTree,i_dwPos*2+1);
    608     }
    609     else{
    610     }
    611     if(i_ptSeqBiTree[i_dwPos*2+2].iData!=0)// 右子树不空
    612     {
    613         PreTraverseSeqBiTree(i_ptSeqBiTree,i_dwPos*2+2);
    614     }
    615     else{
    616     }
    617 }
    618 /*****************************************************************************
    619 -Fuction        : PreOrderTraverseSeqBiTree
    620 -Description    :
    621 -Input            : 
    622 -Output         : 
    623 -Return         : 
    624 * Modify Date      Version         Author           Modification
    625 * -----------------------------------------------
    626 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    627 ******************************************************************************/
    628 static void PreOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree)
    629 {
    630     if(IsSeqBiTreeEmpty(i_ptSeqBiTree))
    631     {
    632         printf("SeqBiTreeEmpty PreOrderTraverseSeqBiTree err
    ");
    633     }
    634     else
    635     {
    636         PreTraverseSeqBiTree(i_ptSeqBiTree,0);
    637         printf("
    ");
    638     }
    639 }
    640 /*****************************************************************************
    641 -Fuction        : InTraverseSeqBiTree
    642 -Description    :
    643 -Input            : 
    644 -Output         : 
    645 -Return         : 
    646 * Modify Date      Version         Author           Modification
    647 * -----------------------------------------------
    648 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    649 ******************************************************************************/
    650 static void InTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,int i_dwPos)
    651 {
    652     if(i_ptSeqBiTree[i_dwPos*2+1].iData!=0)// 左子树不空
    653     {
    654         InTraverseSeqBiTree(i_ptSeqBiTree,i_dwPos*2+1);
    655     }
    656     else{
    657     }
    658     printf("%d ",i_ptSeqBiTree[i_dwPos].iData);
    659     if(i_ptSeqBiTree[i_dwPos*2+2].iData!=0)// 右子树不空
    660     {
    661         InTraverseSeqBiTree(i_ptSeqBiTree,i_dwPos*2+2);
    662     }
    663     else{
    664     }
    665 }
    666 /*****************************************************************************
    667 -Fuction        : InOrderTraverseSeqBiTree
    668 -Description    :
    669 -Input            : 
    670 -Output         : 
    671 -Return         : 
    672 * Modify Date      Version         Author           Modification
    673 * -----------------------------------------------
    674 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    675 ******************************************************************************/
    676 static void InOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree)
    677 {
    678     if(IsSeqBiTreeEmpty(i_ptSeqBiTree))
    679     {
    680         printf("SeqBiTreeEmpty InOrderTraverseSeqBiTree err
    ");
    681     }
    682     else
    683     {
    684         InTraverseSeqBiTree(i_ptSeqBiTree,0);
    685         printf("
    ");
    686     }
    687 }
    688 /*****************************************************************************
    689 -Fuction        : PostTraverseSeqBiTree
    690 -Description    :
    691 -Input            : 
    692 -Output         : 
    693 -Return         : 
    694 * Modify Date      Version         Author           Modification
    695 * -----------------------------------------------
    696 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    697 ******************************************************************************/
    698 static void PostTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree,int i_dwPos)
    699 {
    700     if(i_ptSeqBiTree[i_dwPos*2+1].iData!=0)// 左子树不空
    701     {
    702         PostTraverseSeqBiTree(i_ptSeqBiTree,i_dwPos*2+1);
    703     }
    704     else{
    705     }
    706     if(i_ptSeqBiTree[i_dwPos*2+2].iData!=0)// 右子树不空
    707     {
    708         PostTraverseSeqBiTree(i_ptSeqBiTree,i_dwPos*2+2);
    709     }
    710     else{
    711     }
    712     printf("%d ",i_ptSeqBiTree[i_dwPos].iData);
    713 }
    714 /*****************************************************************************
    715 -Fuction        : PostOrderTraverseSeqBiTree
    716 -Description    :
    717 -Input            : 
    718 -Output         : 
    719 -Return         : 
    720 * Modify Date      Version         Author           Modification
    721 * -----------------------------------------------
    722 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    723 ******************************************************************************/
    724 static void PostOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree)
    725 {
    726     if(IsSeqBiTreeEmpty(i_ptSeqBiTree))
    727     {
    728         printf("SeqBiTreeEmpty PostOrderTraverseSeqBiTree err
    ");
    729     }
    730     else
    731     {
    732         PostTraverseSeqBiTree(i_ptSeqBiTree,0);
    733         printf("
    ");
    734     }
    735 }
    736 /*****************************************************************************
    737 -Fuction        : LevelOrderTraverseSeqBiTree
    738 -Description    :// 层序遍历二叉树
    739 -Input            : 
    740 -Output         : 
    741 -Return         : 
    742 * Modify Date      Version         Author           Modification
    743 * -----------------------------------------------
    744 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    745 ******************************************************************************/
    746 static void LevelOrderTraverseSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree)
    747 {
    748     int i,j;
    749     i=MAX_SEQ_BINARY_TREE_LEN-1;
    750     while(i_ptSeqBiTree[i].iData==0)
    751     {
    752         i--;// 找到最后一个非空结点的序号
    753     }
    754     for(j=0;j<=i;j++)// 从根结点起,按层序遍历二叉树
    755     {
    756         if(0==i_ptSeqBiTree[j].iData)
    757         {
    758         }
    759         else
    760         {
    761             printf("%d ",i_ptSeqBiTree[j].iData);// 只遍历非空的结点
    762         }
    763     }
    764     printf("
    ");
    765 }
    766 /*****************************************************************************
    767 -Fuction        : PrintfSeqBiTree
    768 -Description    :// 逐层、按本层序号输出二叉树
    769 -Input            : 
    770 -Output         : 
    771 -Return         : 
    772 * Modify Date      Version         Author           Modification
    773 * -----------------------------------------------
    774 * 2017/05/08      V1.0.0         Yu Weifeng       Created
    775 ******************************************************************************/
    776 static void PrintfSeqBiTree(T_SeqBiTreeElement *i_ptSeqBiTree)
    777 {
    778     int i,j;
    779     T_PositionInTree tPos={0};
    780     T_SeqBiTreeElement tSeqBiTreeElement={0};
    781     for(i=1;i<=GetSeqBiTreeDepth(i_ptSeqBiTree);i++)
    782     {
    783         printf("第%d层: ",i);
    784         for(j=1;j<=pow(2,i-1);j++)
    785         {
    786             tPos.iLevel=i;
    787             tPos.iOrder=j;
    788             tSeqBiTreeElement=GetSeqBiTreeElement(i_ptSeqBiTree,&tPos);
    789             if(0==tSeqBiTreeElement.iData)
    790             {
    791             }
    792             else
    793             {
    794                 printf("%d:%d ",j,tSeqBiTreeElement.iData);
    795             }
    796         }
    797         printf("
    ");
    798     }
    799 }
    SeqBiTree.c

    3)孩子兄弟法表示的树

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     ChildSiblingTree.c
      5 * Description        :     ChildSiblingTree operation center
      6 * Created            :     2017.05.23.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include "stdio.h"
     13 #include "malloc.h"
     14 #include "stdlib.h"
     15 #include "string.h"
     16 #include "math.h"
     17 #include "ChildSiblingTree.h"
     18 #include "LinkQueue.c"
     19 
     20 static void InitChildSiblingTree(T_ChildSiblingTreeNode **i_pptChildSiblingTree);
     21 static void DestroyChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree);
     22 static int IsChildSiblingTreeEmpty(T_ChildSiblingTreeNode *i_ptChildSiblingTree);
     23 static int GetChildSiblingTreeDepth(T_ChildSiblingTreeNode *i_ptChildSiblingTree);
     24 static char GetChildSiblingTreeNodeData(T_ChildSiblingTreeNode *i_ptChildSiblingTreeNode);
     25 static char GetChildSiblingTreeRootData(T_ChildSiblingTreeNode *i_ptChildSiblingTree);
     26 static int AssignToChildSiblingTreeNode(T_ChildSiblingTreeNode *i_ptChildSiblingBiTree,char i_cCurData,char i_cNewData);
     27 
     28 static char GetChildSiblingTreeParentData(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cCurData);
     29 static char GetChildSiblingTreeLeftChildData(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cCurData);
     30 static char GetChildSiblingTreeRightSiblingData(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cCurData);
     31 
     32 
     33 static void CreateChildSiblingTree(T_ChildSiblingTreeNode **i_pptChildSiblingTree);
     34 static T_ChildSiblingTreeNode  *GetChildSiblingTreeNodePoint(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cData);
     35 static int InsertChildInChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree,T_ChildSiblingTreeNode *i_ptInsertNode,int i,T_ChildSiblingTreeNode *i_ptInsertTree);
     36 static int DeleteChildInChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree,T_ChildSiblingTreeNode *i_ptDeleteNode,int i);
     37 static void PreOrderTraverseChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree);
     38 static void PostOrderTraverseChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree);
     39 static void LevelOrderTraverseChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree);
     40 
     41 
     42 #define     ClearChildSiblingTree     DestroyChildSiblingTree     // 清空二叉树和销毁二叉树的操作一样
     43 #define     NIL             ' '
     44 /*****************************************************************************
     45 -Fuction        : main
     46 -Description    : main
     47 -Input            : 
     48 -Output         : 
     49 -Return         : 
     50 * Modify Date      Version         Author           Modification
     51 * -----------------------------------------------
     52 * 2017/05/25      V1.0.0         Yu Weifeng       Created
     53 ******************************************************************************/
     54 int main(int argc,char **argv)
     55 {
     56     T_ChildSiblingTreeNode *ptChildSiblingTree=NULL;    
     57     T_ChildSiblingTreeNode *ptChildSiblingTreeNoRightChildTree=NULL;
     58     T_ChildSiblingTreeNode *ptChildSiblingTreeNode=NULL;
     59     int i=0;
     60     char cData;
     61     char cOtherData;
     62     InitChildSiblingTree(&ptChildSiblingTree);
     63     printf("构造空树后,树空否? %d(1:是0:否) 树根为%c 树的深度为%d
    ",IsChildSiblingTreeEmpty(ptChildSiblingTree),
     64         GetChildSiblingTreeRootData(ptChildSiblingTree),GetChildSiblingTreeDepth(ptChildSiblingTree));
     65     CreateChildSiblingTree(&ptChildSiblingTree);
     66     printf("构造树T后,树空否? %d(1:是0:否) 树根为%c 树的深度为%d
    ",IsChildSiblingTreeEmpty(ptChildSiblingTree),
     67         GetChildSiblingTreeRootData(ptChildSiblingTree),GetChildSiblingTreeDepth(ptChildSiblingTree));
     68     printf("先根遍历树T:
    ");
     69     PreOrderTraverseChildSiblingTree(ptChildSiblingTree);
     70     
     71 
     72     printf("
    请输入待修改的结点的值,新值: ");
     73     scanf("%c,%c%*c",&cData,&cOtherData);
     74     AssignToChildSiblingTreeNode(ptChildSiblingTree,cData,cOtherData);
     75     printf("后根遍历修改后的树T:
    ");
     76     PostOrderTraverseChildSiblingTree(ptChildSiblingTree);
     77     printf("
    %c的双亲是%c,长子是%c,下一个兄弟是%c
    ",cOtherData,GetChildSiblingTreeParentData(ptChildSiblingTree,cOtherData),
     78         GetChildSiblingTreeLeftChildData(ptChildSiblingTree,cOtherData),GetChildSiblingTreeRightSiblingData(ptChildSiblingTree,cOtherData));
     79 
     80 
     81     printf("建立树p:
    ");
     82     InitChildSiblingTree(&ptChildSiblingTreeNoRightChildTree);
     83     CreateChildSiblingTree(&ptChildSiblingTreeNoRightChildTree);
     84     printf("层序遍历树p:
    ");
     85     LevelOrderTraverseChildSiblingTree(ptChildSiblingTreeNoRightChildTree);
     86 
     87     printf("
    将树p插到树T中,请输入T中p的双亲结点,子树序号: ");
     88     scanf("%c,%d%*c",&cData,&i);
     89     ptChildSiblingTreeNode=GetChildSiblingTreeNodePoint(ptChildSiblingTree,cData);
     90     InsertChildInChildSiblingTree(ptChildSiblingTree,ptChildSiblingTreeNode,i,ptChildSiblingTreeNoRightChildTree);
     91     printf("层序遍历树T:
    ");
     92     LevelOrderTraverseChildSiblingTree(ptChildSiblingTree);
     93 
     94     printf("
    删除树T中结点e的第i棵子树,请输入e,i: ");
     95     scanf("%c,%d",&cData,&i);
     96     ptChildSiblingTreeNode=GetChildSiblingTreeNodePoint(ptChildSiblingTree,cData);
     97     DeleteChildInChildSiblingTree(ptChildSiblingTree,ptChildSiblingTreeNode,i);
     98     printf("层序遍历树T:
    ");
     99     LevelOrderTraverseChildSiblingTree(ptChildSiblingTree);
    100 
    101     DestroyChildSiblingTree(ptChildSiblingTree);
    102 
    103     return 0;
    104 }
    105 
    106 /*****************************************************************************
    107 -Fuction        : InitChildSiblingTree
    108 -Description    : InitChildSiblingTree
    109 -Input            : 
    110 -Output         : 
    111 -Return         : 
    112 * Modify Date      Version         Author           Modification
    113 * -----------------------------------------------
    114 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    115 ******************************************************************************/
    116 static void InitChildSiblingTree(T_ChildSiblingTreeNode **i_pptChildSiblingTree)
    117 {
    118     *i_pptChildSiblingTree=NULL;
    119 }
    120 
    121 /*****************************************************************************
    122 -Fuction        : DestroyChildSiblingTree
    123 -Description    : DestroyChildSiblingTree
    124 -Input            : 
    125 -Output         : 
    126 -Return         : 
    127 * Modify Date      Version         Author           Modification
    128 * -----------------------------------------------
    129 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    130 ******************************************************************************/
    131 static void DestroyChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree)
    132 {
    133     if(NULL==i_ptChildSiblingTree)
    134     {
    135     }
    136     else
    137     {
    138         if(NULL==i_ptChildSiblingTree->ptFirstChild)
    139         {
    140         }
    141         else
    142         {
    143             DestroyChildSiblingTree(i_ptChildSiblingTree->ptFirstChild);
    144         }
    145         if(NULL==i_ptChildSiblingTree->ptFirstSibling)
    146         {
    147         }
    148         else
    149         {
    150             DestroyChildSiblingTree(i_ptChildSiblingTree->ptFirstSibling);
    151         }
    152         free(i_ptChildSiblingTree);
    153         i_ptChildSiblingTree=NULL;
    154     }
    155 }
    156 
    157 /*****************************************************************************
    158 -Fuction        : CreateChildSiblingTree
    159 -Description    : CreateChildSiblingTree
    160 -Input            : 
    161 -Output         : 
    162 -Return         : 
    163 * Modify Date      Version         Author           Modification
    164 * -----------------------------------------------
    165 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    166 ******************************************************************************/
    167 static void CreateChildSiblingTree(T_ChildSiblingTreeNode **i_pptChildSiblingTree)
    168 {
    169     T_ChildSiblingTreeNode *ptTreeNodeFirstChild=NULL;
    170     char acData[20]={0};
    171     int iStringLen=0;
    172     int i;
    173     T_LinkQueue tLinkQueue={0};
    174     T_QueueDataElement tEnterQueueData={0};
    175     T_QueueDataElement tExitQueueData={0};
    176 
    177     InitLinkQueue(&tLinkQueue);
    178     printf("请输入根结点(字符型,空格为空): ");
    179     scanf("%c%*c",&acData[0]);
    180     if(NIL==acData[0])
    181     {
    182         *i_pptChildSiblingTree=NULL;
    183     }
    184     else
    185     {
    186         *i_pptChildSiblingTree=(T_ChildSiblingTreeNode *)malloc(sizeof(T_ChildSiblingTreeNode));
    187         if(NULL==*i_pptChildSiblingTree)
    188         {
    189         }
    190         else
    191         {
    192             (*i_pptChildSiblingTree)->cData=acData[0];
    193             (*i_pptChildSiblingTree)->ptFirstChild=NULL;
    194             (*i_pptChildSiblingTree)->ptFirstSibling=NULL;
    195             tEnterQueueData.ptData=*i_pptChildSiblingTree;
    196             EnterLinkQueue(&tLinkQueue,tEnterQueueData);
    197             while(0!=IsLinkQueueEmpty(&tLinkQueue))
    198             {
    199                 ExitLinkQueue(&tLinkQueue,&tExitQueueData);
    200                 printf("请按长幼顺序输入结点%c的所有孩子,不超过20个:",tExitQueueData.ptData->cData);
    201                 memset(acData,0,sizeof(acData));
    202                 //fgets从stdin中读字符,直至读到换行符或文件结束
    203                 fgets(acData,sizeof(acData),stdin);//sizeof(acData)为size
    204                 //如果size大于一行的字符串长度,那么当读到换行符时,
    205                 //acData包含换行符并且后面还会加上''
    206                 //如果size小于等于一行的字符串的长度,那么读入size-1个字符
    207                 //acData中不包含换行符并且最后一位保留用来放''
    208                 iStringLen=strlen(acData)-1;//去掉换行符
    209                 //如果是gets,把输入的一行信息存入acData中,然后将换行符置换成串结尾符''。
    210                 //用户要保证缓冲区的长度大于或等于最大的行长
    211                 if(iStringLen>0)// 有孩子
    212                 {// 建立长子结点
    213                     tExitQueueData.ptData->ptFirstChild=(T_ChildSiblingTreeNode *)malloc(sizeof(T_ChildSiblingTreeNode));
    214                     if(NULL==tExitQueueData.ptData->ptFirstChild)
    215                     {
    216                     }
    217                     else
    218                     {
    219                         tEnterQueueData.ptData=tExitQueueData.ptData->ptFirstChild;
    220                         tEnterQueueData.ptData->cData=acData[0];
    221                         for(i=1;i<iStringLen;i++)
    222                         {// 建立下一个兄弟结点
    223                             tEnterQueueData.ptData->ptFirstSibling=(T_ChildSiblingTreeNode *)malloc(sizeof(T_ChildSiblingTreeNode));
    224                             if(NULL==tEnterQueueData.ptData->ptFirstSibling)
    225                             {
    226                             }
    227                             else
    228                             {
    229                                 EnterLinkQueue(&tLinkQueue,tEnterQueueData);// 入队上一个结点
    230                                 tEnterQueueData.ptData=tEnterQueueData.ptData->ptFirstSibling;
    231                                 tEnterQueueData.ptData->cData=acData[i];
    232                             }
    233                         }
    234                         tEnterQueueData.ptData->ptFirstSibling=NULL;
    235                         EnterLinkQueue(&tLinkQueue,tEnterQueueData);// 入队最后一个结点
    236                     }
    237                 }
    238                 else
    239                 {
    240                     tExitQueueData.ptData->ptFirstChild=NULL;// 长子指针为空
    241                     //兄弟结点由上一个结点的孩子确定
    242                 }
    243             }
    244         }
    245     }
    246 }
    247 
    248 /*****************************************************************************
    249 -Fuction        : IsChildSiblingTreeEmpty
    250 -Description    : IsChildSiblingTreeEmpty
    251 -Input            : 
    252 -Output         : 
    253 -Return         : 
    254 * Modify Date      Version         Author           Modification
    255 * -----------------------------------------------
    256 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    257 ******************************************************************************/
    258 static int IsChildSiblingTreeEmpty(T_ChildSiblingTreeNode *i_ptChildSiblingTree)
    259 {
    260     int iRet=-1;
    261     if(NULL==i_ptChildSiblingTree)
    262     {
    263         iRet=0;
    264     }
    265     else
    266     {
    267         iRet=-1;
    268     }
    269     return iRet;
    270 }
    271 
    272 /*****************************************************************************
    273 -Fuction        : GetChildSiblingTreeDepth
    274 -Description    : GetChildSiblingTreeDepth
    275 -Input            : 
    276 -Output         : 
    277 -Return         : 
    278 * Modify Date      Version         Author           Modification
    279 * -----------------------------------------------
    280 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    281 ******************************************************************************/
    282 static int GetChildSiblingTreeDepth(T_ChildSiblingTreeNode *i_ptChildSiblingTree)
    283 {
    284     int iDepth=0,iMaxDepth=0;
    285     T_ChildSiblingTreeNode *ptTreeNode=NULL;
    286     if(NULL==i_ptChildSiblingTree)
    287     {
    288         iMaxDepth=0;
    289     }
    290     else if(NULL==i_ptChildSiblingTree->ptFirstChild)
    291     {
    292         iMaxDepth=1;
    293     }
    294     else
    295     {
    296         for(ptTreeNode=i_ptChildSiblingTree->ptFirstChild;NULL!=ptTreeNode;ptTreeNode=ptTreeNode->ptFirstSibling)
    297         {
    298             iDepth=GetChildSiblingTreeDepth(ptTreeNode);
    299             if(iDepth>iMaxDepth)
    300             {
    301                 iMaxDepth=iDepth;
    302             }
    303             else
    304             {
    305             }
    306         }
    307         iMaxDepth++;
    308     }
    309     return iMaxDepth;
    310 }
    311 
    312 /*****************************************************************************
    313 -Fuction        : GetChildSiblingTreeNodeData
    314 -Description    : GetChildSiblingTreeNodeData
    315 -Input            : 
    316 -Output         : 
    317 -Return         : 
    318 * Modify Date      Version         Author           Modification
    319 * -----------------------------------------------
    320 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    321 ******************************************************************************/
    322 static char GetChildSiblingTreeNodeData(T_ChildSiblingTreeNode *i_ptChildSiblingTreeNode)
    323 {
    324     return i_ptChildSiblingTreeNode->cData;
    325 }
    326 
    327 /*****************************************************************************
    328 -Fuction        : GetChildSiblingTreeRootData
    329 -Description    : GetChildSiblingTreeRootData
    330 -Input            : 
    331 -Output         : 
    332 -Return         : 
    333 * Modify Date      Version         Author           Modification
    334 * -----------------------------------------------
    335 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    336 ******************************************************************************/
    337 static char GetChildSiblingTreeRootData(T_ChildSiblingTreeNode *i_ptChildSiblingTree)
    338 {
    339     if(NULL==i_ptChildSiblingTree)
    340     {
    341         return NIL;
    342     }
    343     else
    344     {
    345         return GetChildSiblingTreeNodeData(i_ptChildSiblingTree);
    346     }
    347 }
    348 
    349 /*****************************************************************************
    350 -Fuction        : GetChildSiblingTreeNodePoint
    351 -Description    : GetChildSiblingTreeNodePoint
    352 -Input            : 
    353 -Output         : 
    354 -Return         : 
    355 * Modify Date      Version         Author           Modification
    356 * -----------------------------------------------
    357 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    358 ******************************************************************************/
    359 static T_ChildSiblingTreeNode  *GetChildSiblingTreeNodePoint(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cData)
    360 {
    361     T_LinkQueue tLinkQueue={0};
    362     T_ChildSiblingTreeNode *ptTreeNode=NULL;
    363     T_QueueDataElement tEnterQueueData={0};
    364     T_QueueDataElement tExitQueueData={0};
    365 
    366     if(NULL==i_ptChildSiblingTree)
    367     {
    368         ptTreeNode=NULL;
    369     }
    370     else
    371     {
    372         InitLinkQueue(&tLinkQueue);
    373         tEnterQueueData.ptData=i_ptChildSiblingTree;
    374         EnterLinkQueue(&tLinkQueue,tEnterQueueData);
    375         while(0!=IsLinkQueueEmpty(&tLinkQueue))
    376         {
    377             ExitLinkQueue(&tLinkQueue,&tExitQueueData);
    378             if(tExitQueueData.ptData->cData==i_cData)
    379             {
    380                 ptTreeNode=tExitQueueData.ptData;
    381                 break;
    382             }
    383             else
    384             {
    385                 if(NULL==tExitQueueData.ptData->ptFirstChild)
    386                 {
    387                 }
    388                 else
    389                 {
    390                     tEnterQueueData.ptData=tExitQueueData.ptData->ptFirstChild;
    391                     EnterLinkQueue(&tLinkQueue,tEnterQueueData);
    392                 }
    393                 
    394                 if(NULL==tExitQueueData.ptData->ptFirstSibling)
    395                 {
    396                 }
    397                 else
    398                 {
    399                     tEnterQueueData.ptData=tExitQueueData.ptData->ptFirstSibling;
    400                     EnterLinkQueue(&tLinkQueue,tEnterQueueData);
    401                 }
    402             }
    403         }
    404     }
    405     return ptTreeNode;
    406 }
    407 
    408 /*****************************************************************************
    409 -Fuction        : AssignToChildSiblingTreeNode
    410 -Description    : AssignToChildSiblingTreeNode
    411 -Input            : 
    412 -Output         : 
    413 -Return         : 
    414 * Modify Date      Version         Author           Modification
    415 * -----------------------------------------------
    416 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    417 ******************************************************************************/
    418 static int AssignToChildSiblingTreeNode(T_ChildSiblingTreeNode *i_ptChildSiblingBiTree,char i_cCurData,char i_cNewData)
    419 {
    420     int iRet=-1;
    421     T_ChildSiblingTreeNode *ptTreeNode=NULL;
    422     if(NULL==i_ptChildSiblingBiTree)
    423     {
    424         iRet=-1;
    425     }
    426     else
    427     {
    428         ptTreeNode=GetChildSiblingTreeNodePoint(i_ptChildSiblingBiTree,i_cCurData);
    429         if(NULL==ptTreeNode)
    430         {
    431             iRet=-1;
    432         }
    433         else
    434         {
    435             ptTreeNode->cData=i_cNewData;// 赋新值
    436             iRet=0;
    437         }
    438     }
    439     return iRet;
    440 }
    441 
    442 /*****************************************************************************
    443 -Fuction        : GetChildSiblingTreeParentData
    444 -Description    : GetChildSiblingTreeParentData
    445 -Input            : 
    446 -Output         : 
    447 -Return         : 
    448 * Modify Date      Version         Author           Modification
    449 * -----------------------------------------------
    450 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    451 ******************************************************************************/
    452 static char GetChildSiblingTreeParentData(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cCurData)
    453 {
    454     char cData=NIL;
    455     T_ChildSiblingTreeNode *ptParent=NULL;
    456     T_LinkQueue tLinkQueue={0};
    457     T_QueueDataElement tEnterQueueElement={0}; 
    458     T_QueueDataElement tExitQueueElement={0};
    459     if(NULL==i_ptChildSiblingTree)
    460     {
    461         cData=NIL;
    462     }
    463     else
    464     {
    465         if(i_ptChildSiblingTree->cData==i_cCurData)// 根结点值为i_cCurData
    466         {
    467             cData==NIL;
    468         }
    469         else
    470         {
    471             InitLinkQueue(&tLinkQueue);
    472             tEnterQueueElement.ptData=i_ptChildSiblingTree;
    473             EnterLinkQueue(&tLinkQueue,tEnterQueueElement);
    474             while(0!=IsLinkQueueEmpty(&tLinkQueue))
    475             {
    476                 ExitLinkQueue(&tLinkQueue,&tExitQueueElement);
    477                 if(NULL==tExitQueueElement.ptData->ptFirstChild)
    478                 {
    479                     cData==NIL;
    480                 }
    481                 else
    482                 {
    483                     if(i_cCurData==tExitQueueElement.ptData->ptFirstChild->cData)// 长子为i_cCurData
    484                     {
    485                         cData=tExitQueueElement.ptData->cData;// 返回双亲
    486                         break;
    487                     }
    488                     else
    489                     {
    490                         ptParent=tExitQueueElement.ptData;// 双亲指针赋给ptParent
    491                         tEnterQueueElement.ptData=tExitQueueElement.ptData->ptFirstChild;// tEnterQueueElement.ptData指向长子
    492                         EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 入队长子
    493                         while(NULL!=tEnterQueueElement.ptData->ptFirstSibling)//结点的孩子判断完了接着判断兄弟
    494                         {
    495                             tEnterQueueElement.ptData=tEnterQueueElement.ptData->ptFirstSibling;
    496                             if(GetChildSiblingTreeNodeData(tEnterQueueElement.ptData)==i_cCurData)//兄弟相等,即次子为对应要找的数据
    497                             {
    498                                 cData=GetChildSiblingTreeNodeData(tExitQueueElement.ptData);//对应数据的双亲返回
    499                                 break;
    500                             }
    501                             else//没找到,入队该兄弟结点
    502                             {
    503                                 EnterLinkQueue(&tLinkQueue,tEnterQueueElement);
    504                             }
    505                         }            
    506                     }
    507                 }
    508             }
    509         }
    510     }
    511     return cData;
    512 }
    513 
    514 /*****************************************************************************
    515 -Fuction        : GetChildSiblingTreeLeftChildData
    516 -Description    : GetChildSiblingTreeLeftChildData
    517 -Input            : 
    518 -Output         : 
    519 -Return         : 
    520 * Modify Date      Version         Author           Modification
    521 * -----------------------------------------------
    522 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    523 ******************************************************************************/
    524 static char GetChildSiblingTreeLeftChildData(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cCurData)
    525 {
    526     char cData=NIL;
    527     T_ChildSiblingTreeNode *ptTreeNode=NULL;
    528     ptTreeNode=GetChildSiblingTreeNodePoint(i_ptChildSiblingTree,i_cCurData);
    529     if(NULL!=ptTreeNode&&NULL!=ptTreeNode->ptFirstChild)// 找到结点 且结点 有长子
    530     {
    531         cData=ptTreeNode->ptFirstChild->cData;
    532     }
    533     else
    534     {
    535         cData=NIL;
    536     }
    537     return cData;
    538 }
    539 
    540 /*****************************************************************************
    541 -Fuction        : GetChildSiblingTreeRightSiblingData
    542 -Description    : GetChildSiblingTreeRightSiblingData
    543 -Input            : 
    544 -Output         : 
    545 -Return         : 
    546 * Modify Date      Version         Author           Modification
    547 * -----------------------------------------------
    548 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    549 ******************************************************************************/
    550 static char GetChildSiblingTreeRightSiblingData(T_ChildSiblingTreeNode *i_ptChildSiblingTree,char i_cCurData)
    551 {
    552     char cData=NIL;
    553     T_ChildSiblingTreeNode *ptTreeNode=NULL;
    554     ptTreeNode=GetChildSiblingTreeNodePoint(i_ptChildSiblingTree,i_cCurData);
    555     if(NULL!=ptTreeNode&&NULL!=ptTreeNode->ptFirstSibling)// 找到结点 且结点 有长子
    556     {
    557         cData=ptTreeNode->ptFirstSibling->cData;
    558     }
    559     else
    560     {
    561         cData=NIL;
    562     }
    563     return cData;
    564 }
    565 
    566 /*****************************************************************************
    567 -Fuction        : InsertChildInChildSiblingTree
    568 -Description    : 
    569 // 初始条件:树i_ptChildSiblingTree存在,i_ptInsertNode指向i_ptChildSiblingTree中某个结点,
    570 1≤i≤p所指结点的度+1,非空树i_ptInsertTree与i_ptChildSiblingTree不相交
    571 // 操作结果:插入i_ptInsertTree为i_ptChildSiblingTree中i_ptInsertNode结点的第i棵子树
    572 
    573 -Input            : 
    574 -Output         : 
    575 -Return         : 
    576 * Modify Date      Version         Author           Modification
    577 * -----------------------------------------------
    578 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    579 ******************************************************************************/
    580 static int InsertChildInChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree,T_ChildSiblingTreeNode *i_ptInsertNode,int i,T_ChildSiblingTreeNode *i_ptInsertTree)
    581 {
    582     int iRet=-1;
    583     int j=0;
    584     if(NULL==i_ptChildSiblingTree)
    585     {
    586         iRet=-1;
    587     }
    588     else// i_ptChildSiblingTree不空
    589     {
    590         if(1==i)// 插入i_ptInsertTree为i_ptInsertNode的长子
    591         {
    592             i_ptInsertTree->ptFirstSibling=i_ptInsertNode->ptFirstChild;//被覆盖的放在右子树
    593             i_ptInsertNode->ptFirstChild=i_ptInsertTree;
    594             iRet=0;
    595         }
    596         else// 找插入点
    597         {
    598             i_ptInsertNode=i_ptInsertNode->ptFirstChild;
    599             j=2;//到这里至少指向次子,第二个儿子,度为2
    600             while(NULL!=i_ptInsertNode&&j<i)//使用还需要i_ptInsertNode->ptFirstSibling表示次子
    601             {
    602                 i_ptInsertNode=i_ptInsertNode->ptFirstSibling;//指向度为i-1的孩子
    603                 j++;//使用还需要i_ptInsertNode->ptFirstSibling表示度为i的孩子
    604             }
    605             if(j==i)
    606             {
    607                 i_ptInsertTree->ptFirstSibling=i_ptInsertNode->ptFirstSibling;
    608                 i_ptInsertNode->ptFirstSibling=i_ptInsertTree;
    609                 iRet=0;
    610             }
    611             else// 原有孩子数小于i-1
    612             {
    613                 iRet=-1;
    614             }
    615         }
    616     }
    617     return iRet;
    618 }
    619 
    620 /*****************************************************************************
    621 -Fuction        : DeleteChildInChildSiblingTree
    622 -Description    : 
    623 // 初始条件:树i_ptChildSiblingTree存在,i_ptDeleteNode指向i_ptChildSiblingTree中某个结点,
    624 1≤i≤i_ptDeleteNode所指结点的度
    625 // 操作结果:删除i_ptChildSiblingTree中i_ptDeleteNode所指结点的第i棵子树
    626 -Input            : 
    627 -Output         : 
    628 -Return         : 
    629 * Modify Date      Version         Author           Modification
    630 * -----------------------------------------------
    631 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    632 ******************************************************************************/
    633 static int DeleteChildInChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree,T_ChildSiblingTreeNode *i_ptDeleteNode,int i)
    634 {
    635     int iRet=-1;
    636     int j;
    637     T_ChildSiblingTreeNode *ptDeleteNode=NULL;
    638     if(NULL==i_ptChildSiblingTree)
    639     {
    640         iRet=-1;
    641     }
    642     else
    643     {
    644         if(1==i)// 删除长子
    645         {
    646             ptDeleteNode=i_ptDeleteNode->ptFirstChild;
    647             i_ptDeleteNode->ptFirstChild=ptDeleteNode->ptFirstSibling;// i_ptDeleteNode的原次子现是长子
    648             ptDeleteNode->ptFirstSibling=NULL;
    649             DestroyChildSiblingTree(ptDeleteNode);
    650             iRet=0;
    651         }
    652         else// 删除非长子
    653         {
    654             i_ptDeleteNode=i_ptDeleteNode->ptFirstChild;
    655             j=2;//到这里至少指向次子,第二个儿子,度为2
    656             while(NULL!=i_ptDeleteNode&&j<i)//使用还需要i_ptDeleteNode->ptFirstSibling表示次子
    657             {
    658                 i_ptDeleteNode=i_ptDeleteNode->ptFirstSibling;//指向度为i-1的孩子
    659                 j++;//使用还需要i_ptInsertNode->ptFirstSibling表示度为i的孩子
    660             }
    661             if(j==i)// 找到第i棵子树
    662             {
    663                 ptDeleteNode=i_ptDeleteNode->ptFirstSibling;
    664                 i_ptDeleteNode->ptFirstSibling=ptDeleteNode->ptFirstSibling;
    665                 ptDeleteNode->ptFirstSibling=NULL;
    666                 DestroyChildSiblingTree(ptDeleteNode);
    667                 iRet=0;
    668             }
    669             else//原有孩子数小于i-1(j++导致,DestroyChildSiblingTree null也可以)
    670             {
    671                 iRet=-1;
    672             }
    673         }
    674     }
    675     return iRet;
    676 }
    677 
    678 /*****************************************************************************
    679 -Fuction        : PreOrderTraverseChildSiblingTree
    680 -Description    : PreOrderTraverseChildSiblingTree
    681 -Input            : 
    682 -Output         : 
    683 -Return         : 
    684 * Modify Date      Version         Author           Modification
    685 * -----------------------------------------------
    686 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    687 ******************************************************************************/
    688 static void PreOrderTraverseChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree)
    689 {
    690     if(NULL==i_ptChildSiblingTree)
    691     {
    692     }
    693     else
    694     {
    695         printf("%c ",i_ptChildSiblingTree->cData);
    696         PreOrderTraverseChildSiblingTree(i_ptChildSiblingTree->ptFirstChild);
    697         PreOrderTraverseChildSiblingTree(i_ptChildSiblingTree->ptFirstSibling);
    698     }
    699 }
    700 
    701 /*****************************************************************************
    702 -Fuction        : PostOrderTraverseChildSiblingTree
    703 -Description    : 先把孩子遍历完最后再访问根
    704 -Input            : 
    705 -Output         : 
    706 -Return         : 
    707 * Modify Date      Version         Author           Modification
    708 * -----------------------------------------------
    709 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    710 ******************************************************************************/
    711 static void PostOrderTraverseChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree)
    712 {
    713     T_ChildSiblingTreeNode *ptTreeNode=NULL;
    714     if(NULL==i_ptChildSiblingTree)
    715     {
    716     }
    717     else
    718     {
    719         if(NULL==i_ptChildSiblingTree->ptFirstChild)
    720         {
    721         }
    722         else
    723         {
    724             PostOrderTraverseChildSiblingTree(i_ptChildSiblingTree->ptFirstChild);
    725             ptTreeNode=i_ptChildSiblingTree->ptFirstChild->ptFirstSibling;// 指向长子的下一个兄弟
    726             while(NULL!=ptTreeNode)
    727             {
    728                 PostOrderTraverseChildSiblingTree(ptTreeNode);
    729                 ptTreeNode=ptTreeNode->ptFirstSibling;
    730             }
    731         }//当退出循环时ptTreeNode为null
    732         printf("%c ",GetChildSiblingTreeNodeData(i_ptChildSiblingTree));//即这里不能使用ptTreeNode
    733     }
    734 }
    735 
    736 /*****************************************************************************
    737 -Fuction        : LevelOrderTraverseChildSiblingTree
    738 -Description    : 层序遍历孩子—兄弟二叉链表结构的树
    739 -Input            : 
    740 -Output         : 
    741 -Return         : 
    742 * Modify Date      Version         Author           Modification
    743 * -----------------------------------------------
    744 * 2017/05/25      V1.0.0         Yu Weifeng       Created
    745 ******************************************************************************/
    746 static void LevelOrderTraverseChildSiblingTree(T_ChildSiblingTreeNode *i_ptChildSiblingTree)
    747 {
    748     T_ChildSiblingTreeNode *ptTreeNode=NULL;
    749     T_LinkQueue tLinkQueue;
    750     T_QueueDataElement tEnterQueueElement;
    751     T_QueueDataElement tExitQueueElement;
    752     InitLinkQueue(&tLinkQueue);
    753     if(NULL==i_ptChildSiblingTree)
    754     {
    755     }
    756     else
    757     {
    758         tEnterQueueElement.ptData=i_ptChildSiblingTree;
    759         printf("%c ",tEnterQueueElement.ptData->cData);
    760         EnterLinkQueue(&tLinkQueue,tEnterQueueElement);
    761         while(0!=IsLinkQueueEmpty(&tLinkQueue))
    762         {
    763             ExitLinkQueue(&tLinkQueue,&tExitQueueElement);
    764             if(NULL==tExitQueueElement.ptData->ptFirstChild)
    765             {
    766             }
    767             else
    768             {
    769                 tEnterQueueElement.ptData=tExitQueueElement.ptData->ptFirstChild;
    770                 printf("%c ",tEnterQueueElement.ptData->cData);
    771                 EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 入队长子结点的指针
    772                 while(NULL!=tEnterQueueElement.ptData->ptFirstSibling)
    773                 {
    774                     tEnterQueueElement.ptData=tEnterQueueElement.ptData->ptFirstSibling;
    775                     printf("%c ",tEnterQueueElement.ptData->cData);
    776                     EnterLinkQueue(&tLinkQueue,tEnterQueueElement);// 入队兄弟结点的指针
    777                 }
    778             }
    779         }
    780     }
    781 }
    ChildSiblingTree.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     ChildSiblingTree.h
     5 * Description        :     ChildSiblingTree operation center
     6 * Created            :     2017.05.23.
     7 * Author            :     Yu Weifeng
     8 * Function List         :     
     9 * Last Modified     :     
    10 * History            :     
    11 ******************************************************************************/
    12 #ifndef _CHILD_SIBLING_TREE_H
    13 #define _CHILD_SIBLING_TREE_H
    14 
    15 
    16 typedef struct ChildSiblingTreeNode
    17 {
    18     char cData;
    19     struct ChildSiblingTreeNode *ptFirstChild;
    20     struct ChildSiblingTreeNode *ptFirstSibling;
    21 }T_ChildSiblingTreeNode,*PT_ChildSiblingTreeNode;
    22 
    23 
    24 
    25 
    26 
    27 
    28 
    29 #endif
    ChildSiblingTree.h

    5.图

    1)邻接表表示的图

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     AdjacencyListGraph.c
      5 * Description        :     AdjacencyListGraph operation center
      6 * Created            :     2017.06.02.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 #include "LinkListClearOprNoHeadNode.c"
     17 
     18 
     19 static int PutVertexNewData(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData,T_VertexData *i_ptVertexNewData);
     20 
     21 static void InitAdjacencyListGraph(T_AdjacencyListGraph *i_ptAdjacencyListGraph);
     22 static void InsertVertex(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData);
     23 static int InsertArc(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData,T_VertexData *i_ptAdjVertexData);
     24 static int DeleteArc(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData,T_VertexData *i_ptAdjVertexData);
     25 static int DeleteVertex(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData);
     26 
     27 static void DisplayGraph(T_AdjacencyListGraph *i_ptAdjacencyListGraph);
     28 static void DestroyGraph(T_AdjacencyListGraph *i_ptAdjacencyListGraph);
     29 /*****************************************************************************
     30 -Fuction        : main
     31 -Description    : main
     32 -Input            : 
     33 -Output         : 
     34 -Return         : 
     35 * Modify Date      Version         Author           Modification
     36 * -----------------------------------------------
     37 * 2017/06/01      V1.0.0         Yu Weifeng       Created
     38 ******************************************************************************/
     39 /*int main(int argc,char **argv)
     40 {
     41     int i,j,k,n;
     42     T_AdjacencyListGraph tGraph;
     43     T_VertexData v1,v2;
     44     printf("请顺序选择有向图,有向网,无向图,无向网
    ");
     45     for(i=0;i<4;i++) // 验证4种情况
     46     {
     47         InitAdjacencyListGraph(&tGraph);
     48         DisplayGraph(&tGraph);
     49         printf("插入新顶点,请输入顶点的值: ");
     50         scanf("%s",v1.acData);
     51         InsertVertex(&tGraph,&v1);
     52         printf("插入与新顶点有关的弧或边,请输入弧或边数: ");
     53         scanf("%d",&n);
     54         for(k=0;k<n;k++)
     55         {
     56             printf("请输入另一顶点的值: ");
     57             scanf("%s",v2.acData);
     58             if(tGraph.iKind<=1) // 有向
     59             {
     60                 printf("对于有向图或网,请输入另一顶点的方向(0:弧头1:弧尾): ");
     61                 scanf("%d",&j);
     62                 if(j)
     63                 InsertArc(&tGraph,&v2,&v1);
     64                 else
     65                 InsertArc(&tGraph,&v1,&v2);
     66             }
     67             else // 无向
     68             {
     69                 InsertArc(&tGraph,&v1,&v2);
     70             }
     71         }
     72         DisplayGraph(&tGraph);
     73         if(i==3)
     74         {
     75             printf("删除一条边或弧,请输入待删除边或弧的弧尾弧头:");
     76             scanf("%s%s",v1.acData,v2.acData);
     77             DeleteArc(&tGraph,&v1,&v2);
     78             printf("修改顶点的值,请输入原值新值: ");
     79             scanf("%s%s",v1.acData,v2.acData);
     80             PutVertexNewData(&tGraph,&v1,&v2);
     81         }
     82         printf("删除顶点及相关的弧或边,请输入顶点的值: ");
     83         scanf("%s",v1.acData);
     84         DeleteVertex(&tGraph,&v1);
     85         DisplayGraph(&tGraph);
     86         DestroyGraph(&tGraph);
     87     }
     88 }*/
     89 
     90 /*****************************************************************************
     91 -Fuction        : LocateVertex
     92 -Description    : 
     93 // 操作结果:若G中存在顶点i_ptVertexData,则返回该顶点在图中位置
     94 ;否则返回-1
     95 -Input            : 
     96 -Output         : 
     97 -Return         : 
     98 * Modify Date      Version         Author           Modification
     99 * -----------------------------------------------
    100 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    101 ******************************************************************************/
    102 static int LocateVertex(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData)
    103 {
    104     int i;
    105     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;i++)
    106     {
    107         if(0==strncmp(i_ptAdjacencyListGraph->atVertexList[i].tData.acData,i_ptVertexData->acData,MAX_NAME))
    108         {
    109             break;
    110         }
    111         else
    112         {
    113         }
    114     }
    115     if(i<i_ptAdjacencyListGraph->iVexNum)
    116     {
    117     }
    118     else
    119     {
    120         i=-1;
    121     }
    122     return i;
    123 }
    124 
    125 /*****************************************************************************
    126 -Fuction        : InitAdjacencyListGraph
    127 -Description    : 
    128 // 采用邻接表存储结构,构造没有相关信息图或网G(用一个函数构造4种图)
    129 
    130 -Input            : 
    131 -Output         : 
    132 -Return         : 
    133 * Modify Date      Version         Author           Modification
    134 * -----------------------------------------------
    135 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    136 ******************************************************************************/
    137 static void InitAdjacencyListGraph(T_AdjacencyListGraph *i_ptAdjacencyListGraph)
    138 {
    139     int i,j,k,w; // w是权值
    140     T_VertexNode tVa,tVb; // 连接边或弧的2顶点
    141     T_LinkListElement tElement;
    142     printf("请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3): ");
    143     scanf("%d",&i_ptAdjacencyListGraph->iKind);
    144     printf("请输入图的顶点数,边数: ");
    145     scanf("%d,%d",&i_ptAdjacencyListGraph->iVexNum,&i_ptAdjacencyListGraph->iArcNum);
    146     printf("请输入%d个顶点的值(<%d个字符):
    ",i_ptAdjacencyListGraph->iVexNum,MAX_NAME);
    147     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;++i) // 构造顶点向量
    148     {
    149         scanf("%s",i_ptAdjacencyListGraph->atVertexList[i].tData.acData);
    150         i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode=NULL; // 初始化与该顶点有关的出弧链表
    151     }
    152     if(i_ptAdjacencyListGraph->iKind%2) //
    153     printf("请输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):
    ");
    154     else //
    155     printf("请输入每条弧(边)的弧尾和弧头(以空格作为间隔):
    ");
    156     for(k=0;k<i_ptAdjacencyListGraph->iArcNum;++k) // 构造相关弧链表
    157     {
    158         if(i_ptAdjacencyListGraph->iKind%2) //
    159         scanf("%d%s%s",&w,tVa.tData.acData,tVb.tData.acData);
    160         else //
    161         scanf("%s%s",tVa.tData.acData,tVb.tData.acData);
    162         i=LocateVertex(i_ptAdjacencyListGraph,&tVa.tData); // 弧尾
    163         j=LocateVertex(i_ptAdjacencyListGraph,&tVb.tData); // 弧头
    164         tElement.pcInfo=NULL; // 给待插表结点e赋值,图无权
    165         tElement.iAdjvex=j; // 弧头
    166         if(i_ptAdjacencyListGraph->iKind%2) //
    167         {
    168             tElement.pcInfo=(T_InfoType *)malloc(sizeof(T_InfoType)); // 动态生成存放权值的空间
    169             tElement.pcInfo->iWeight=w;
    170         }
    171         else{
    172         }
    173         InsertNodeToLinkList(&i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode,1,&tElement); // 插在第i个元素(出弧)的表头
    174         if(i_ptAdjacencyListGraph->iKind>=2) // 无向图或网,产生第2个表结点,并插在第j个元素(入弧)的表头
    175         {//无向
    176             tElement.iAdjvex=i; // e.info不变,不必再赋值
    177             InsertNodeToLinkList(&i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode,1,&tElement); // 插在第j个元素的表头
    178         }
    179         else
    180         {
    181         }
    182     }
    183 }
    184 
    185 /*****************************************************************************
    186 -Fuction        : CreateAdjacencyListGraphFromFile
    187 -Description    :
    188 // 采用邻接表存储结构,由文件构造没有相关信息图或网G(用一个函数构造4种图)
    189 -Input            : 
    190 -Output         : 
    191 -Return         : 
    192 * Modify Date      Version         Author           Modification
    193 * -----------------------------------------------
    194 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    195 ******************************************************************************/
    196 static void CreateAdjacencyListGraphFromFile(T_AdjacencyListGraph *i_ptAdjacencyListGraph)
    197 {
    198     int i,j,k,w; // w是权值
    199     T_VertexNode tVa,tVb; // 连接边或弧的2顶点
    200     T_LinkListElement tElement;
    201     char strFileName[30]={0};
    202     FILE *fileGraphList;
    203     printf("请输入数据文件名(f7-1.txt或f7-2.txt):");
    204     scanf("%s",strFileName);
    205     printf("请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3): ");
    206     scanf("%d",&i_ptAdjacencyListGraph->iKind);
    207     fileGraphList=fopen(strFileName,"r"); // 以读的方式打开数据文件,并以fileGraphList表示
    208     fscanf(fileGraphList,"%d",&i_ptAdjacencyListGraph->iVexNum);
    209     fscanf(fileGraphList,"%d",&i_ptAdjacencyListGraph->iArcNum);
    210     
    211     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;++i) // 构造顶点向量
    212     {
    213         fscanf(fileGraphList,"%s",i_ptAdjacencyListGraph->atVertexList[i].tData.acData);
    214         i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode=NULL; // 初始化与该顶点有关的出弧链表
    215     }
    216     for(k=0;k<i_ptAdjacencyListGraph->iArcNum;++k) // 构造相关弧链表
    217     {
    218         if(i_ptAdjacencyListGraph->iKind%2) //
    219         fscanf(fileGraphList,"%d%s%s",&w,tVa.tData.acData,tVb.tData.acData);
    220         else //
    221         fscanf(fileGraphList,"%s%s",tVa.tData.acData,tVb.tData.acData);
    222         i=LocateVertex(i_ptAdjacencyListGraph,&tVa.tData); // 弧尾
    223         j=LocateVertex(i_ptAdjacencyListGraph,&tVb.tData); // 弧头
    224         tElement.pcInfo=NULL; // 给待插表结点e赋值,图无权
    225         tElement.iAdjvex=j; // 弧头
    226         if(i_ptAdjacencyListGraph->iKind%2) //
    227         {
    228             tElement.pcInfo=(T_InfoType *)malloc(sizeof(T_InfoType)); // 动态生成存放权值的空间
    229             tElement.pcInfo->iWeight=w;
    230         }
    231         else{
    232         }
    233         InsertNodeToLinkList(&i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode,1,&tElement); // 插在第i个元素(出弧)的表头
    234         if(i_ptAdjacencyListGraph->iKind>=2) // 无向图或网,产生第2个表结点,并插在第j个元素(入弧)的表头
    235         {//无向
    236             tElement.iAdjvex=i; // e.info不变,不必再赋值
    237             InsertNodeToLinkList(&i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode,1,&tElement); // 插在第j个元素的表头
    238         }
    239         else
    240         {
    241         }
    242     }
    243     fclose(fileGraphList); // 关闭数据文件
    244 }
    245 
    246 
    247 /*****************************************************************************
    248 -Fuction        : DestroyGraph
    249 -Description    : 
    250 // 初始条件:图G存在。操作结果:销毁图G
    251 -Input            : 
    252 -Output         : 
    253 -Return         : 
    254 * Modify Date      Version         Author           Modification
    255 * -----------------------------------------------
    256 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    257 ******************************************************************************/
    258 static void DestroyGraph(T_AdjacencyListGraph *i_ptAdjacencyListGraph)
    259 {
    260     int i;
    261     T_LinkListElement tElement;
    262     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;i++)
    263     {
    264         if(i_ptAdjacencyListGraph->iKind%2) //
    265         {
    266             while(i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode!=NULL)
    267             {
    268                 DeleteNodeFromLinkList(&i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode,1,&tElement); // 删除链表的第1个结点,并将值赋给e
    269                 if(tElement.iAdjvex>i) // 每个顶点序号>i(保证访问一次即保证动态生成的权值空间只释放1次)
    270                 free(tElement.pcInfo);
    271             }
    272 
    273         }
    274         else
    275         {
    276             DestroyLinkList(i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode); // 销毁弧或边链表,在bo2-8.cpp中
    277         }
    278     }
    279     i_ptAdjacencyListGraph->iVexNum=0; // 顶点数为0
    280     i_ptAdjacencyListGraph->iArcNum=0; // 边或弧数为0
    281 }
    282 
    283 
    284 /*****************************************************************************
    285 -Fuction        : GetVertexData
    286 -Description    : 
    287 // 初始条件:图G存在,v是G中某个顶点的序号。
    288 操作结果:返回v的值
    289 -Input            : 
    290 -Output         : 
    291 -Return         : 
    292 * Modify Date      Version         Author           Modification
    293 * -----------------------------------------------
    294 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    295 ******************************************************************************/
    296 static int GetVertexData(T_AdjacencyListGraph *i_ptAdjacencyListGraph,int i_ptVertexNum,T_VertexData *o_ptVertexData)
    297 {
    298     int iRet=-1;
    299     if(i_ptVertexNum<0||i_ptVertexNum>=i_ptAdjacencyListGraph->iVexNum)
    300     {
    301         iRet=-1;
    302         printf("GetVertexData err
    ");
    303     }
    304     else
    305     {
    306         memcpy(o_ptVertexData,&i_ptAdjacencyListGraph->atVertexList[i_ptVertexNum].tData,sizeof(T_VertexData));
    307         iRet=0;
    308     }
    309 
    310     return iRet;
    311 }
    312 
    313 
    314 /*****************************************************************************
    315 -Fuction        : PutVertexNewData
    316 -Description    : 
    317 // 初始条件:图G存在,v是G中某个顶点。
    318 操作结果:对v赋新值value
    319 -Input            : 
    320 -Output         : 
    321 -Return         : 
    322 * Modify Date      Version         Author           Modification
    323 * -----------------------------------------------
    324 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    325 ******************************************************************************/
    326 static int PutVertexNewData(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData,T_VertexData *i_ptVertexNewData)
    327 {
    328     int iRet=-1;
    329     int iPos=-1;
    330     iPos=LocateVertex(i_ptAdjacencyListGraph,i_ptVertexData);
    331     if(iPos>-1) // v是G的顶点
    332     {
    333         memcpy(&i_ptAdjacencyListGraph->atVertexList[iPos].tData,i_ptVertexNewData,sizeof(T_VertexData));
    334         iRet=0;
    335     }
    336     else
    337     {
    338         iRet=-1;
    339         printf("PutVertexNewData err
    ");
    340     }
    341 
    342     return iRet;
    343 }
    344 
    345 
    346 
    347 /*****************************************************************************
    348 -Fuction        : GetFirstAdjacencyVertex
    349 -Description    : 
    350 // 初始条件:图G存在,v是G中某个顶点
    351 // 操作结果:返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1
    352 -Input            : 
    353 -Output         : 
    354 -Return         : 
    355 * Modify Date      Version         Author           Modification
    356 * -----------------------------------------------
    357 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    358 ******************************************************************************/
    359 static int GetFirstAdjacencyVertex(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData)
    360 {
    361     int iNum=-1;
    362     T_ArcNode*ptArcNode=NULL;
    363     iNum=LocateVertex(i_ptAdjacencyListGraph,i_ptVertexData);
    364     if(-1==iNum)
    365     {    
    366     }
    367     else
    368     {
    369         ptArcNode=i_ptAdjacencyListGraph->atVertexList[iNum].ptFirstArcNode;
    370         if(NULL==ptArcNode)
    371         {
    372             iNum=-1;
    373         }
    374         else
    375         {
    376             iNum=ptArcNode->tData.iAdjvex;
    377         }
    378     }
    379     return iNum;
    380 }
    381 
    382 
    383 /*****************************************************************************
    384 -Fuction        : EqualVertex
    385 -Description    : 
    386 -Input            : 
    387 -Output         : 
    388 -Return         : 
    389 * Modify Date      Version         Author           Modification
    390 * -----------------------------------------------
    391 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    392 ******************************************************************************/
    393 static int EqualVertex(T_LinkListElement *i_ptElement1,T_LinkListElement *i_ptElement2)
    394 {
    395     int iRet=-1;
    396     if(i_ptElement1->iAdjvex!=i_ptElement2->iAdjvex)
    397     {
    398         iRet=-1;
    399     }
    400     else
    401     {
    402         iRet=0;
    403     }
    404 
    405     return iRet;
    406 }
    407 
    408 
    409 
    410 /*****************************************************************************
    411 -Fuction        : GetNextAdjacencyVertex
    412 -Description    : 
    413 // 初始条件:图G存在,v(i_ptVertexData)是G中某个顶点,w(i_ptAdjVertexData)是v的邻接顶点
    414 // 操作结果:返回v的(相对于w的)下一个邻接顶点的序号。若w是v的最后一个邻接点,则返回-1
    415 -Input            : 
    416 -Output         : 
    417 -Return         : 
    418 * Modify Date      Version         Author           Modification
    419 * -----------------------------------------------
    420 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    421 ******************************************************************************/
    422 static int GetNextAdjacencyVertex(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData,T_VertexData *i_ptAdjVertexData)
    423 {
    424     int iNum;
    425     int iAdjNextVertexNum=-1;
    426     T_LinkList *ptLinkListNode=NULL;
    427     T_LinkList *ptLinkListPreNode=NULL;
    428     T_LinkListElement tElement={0};
    429     iNum=LocateVertex(i_ptAdjacencyListGraph,i_ptVertexData);// iNum为顶点v在图G中的序号
    430     tElement.iAdjvex=LocateVertex(i_ptAdjacencyListGraph,i_ptAdjVertexData);// tElement.adjvex为顶点w在图G中的序号
    431     ptLinkListNode=GetLinkListNodePoint(i_ptAdjacencyListGraph->atVertexList[iNum].ptFirstArcNode,&tElement,EqualVertex,&ptLinkListPreNode);
    432     if(NULL==ptLinkListNode||NULL==ptLinkListNode->ptNext)// ptLinkListNode指向顶点v的链表中邻接顶点为w的结点
    433     {// 没找到w或w是最后一个邻接点
    434         iAdjNextVertexNum=-1;
    435     }
    436     else
    437     {// 返回v的(相对于w的)下一个邻接顶点的序号
    438         iAdjNextVertexNum=ptLinkListNode->ptNext->tData.iAdjvex;
    439     }
    440     return iAdjNextVertexNum;
    441 
    442 }
    443 
    444 
    445 
    446 /*****************************************************************************
    447 -Fuction        : InsertVertex
    448 -Description    : 
    449 // 初始条件:图G存在,v和图中顶点有相同特征
    450 // 操作结果:在图G中增添新顶点v(不增添与顶点相关的弧,留待InsertArc()去做)
    451 -Input            : 
    452 -Output         : 
    453 -Return         : 
    454 * Modify Date      Version         Author           Modification
    455 * -----------------------------------------------
    456 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    457 ******************************************************************************/
    458 static void InsertVertex(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData)
    459 {
    460     memcpy(&i_ptAdjacencyListGraph->atVertexList[i_ptAdjacencyListGraph->iVexNum].tData, i_ptVertexData,sizeof(T_VertexData));// 构造新顶点向量
    461     i_ptAdjacencyListGraph->atVertexList[i_ptAdjacencyListGraph->iVexNum].ptFirstArcNode=NULL;
    462     i_ptAdjacencyListGraph->iVexNum++;// 图G的顶点数加1
    463 
    464 }
    465 
    466 /*****************************************************************************
    467 -Fuction        : DeleteVertex
    468 -Description    : 
    469 // 初始条件:图G存在,v是G中某个顶点。操作结果:删除G中顶点v及其相关的弧
    470 -Input            : 
    471 -Output         : 
    472 -Return         : 
    473 * Modify Date      Version         Author           Modification
    474 * -----------------------------------------------
    475 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    476 ******************************************************************************/
    477 static int DeleteVertex(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData)
    478 {
    479     int iRet=-1;
    480     int i,j,k;    
    481     T_LinkList *ptLinkListNode=NULL;
    482     T_LinkList *ptLinkListPreNode=NULL;
    483     T_LinkListElement tElement={0};
    484     j=LocateVertex(i_ptAdjacencyListGraph,i_ptVertexData);
    485     if(j<0)
    486     {
    487         iRet=-1;
    488         printf("CannotFindVertex:%dr
    ",j);
    489     }
    490     else
    491     {
    492         i=GetLinkListLength(i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode);// 以v为出度的弧或边数
    493         i_ptAdjacencyListGraph->iArcNum-=i;// 边或弧数-i
    494         if(i_ptAdjacencyListGraph->iKind%2)//// 网
    495         {
    496             while(i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode)// 对应的弧或边链表不空
    497             {
    498                 DeleteNodeFromLinkList(&i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode,1,&tElement);// 删除链表的第1个结点,并将值赋给e
    499                 free(tElement.pcInfo);// 释放动态生成的权值空间
    500             }
    501         }
    502         else//
    503         {
    504             DestroyLinkList(i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode);// 销毁弧或边链表
    505         }
    506         i_ptAdjacencyListGraph->iVexNum--;// 顶点数减1(j从0开始,所以前面减一)
    507         for(i=j;i<i_ptAdjacencyListGraph->iVexNum;i++)// 顶点v后面的顶点前移
    508         {
    509             i_ptAdjacencyListGraph->atVertexList[i]=i_ptAdjacencyListGraph->atVertexList[i+1];
    510         }
    511         for(i=0;i<i_ptAdjacencyListGraph->iVexNum;i++)
    512         {// 删除以v为入度的弧或边且必要时修改表结点的顶点位置值
    513             tElement.iAdjvex=j;
    514             ptLinkListNode=GetLinkListNodePoint(i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode,&tElement,EqualVertex,&ptLinkListPreNode);
    515             if(NULL==ptLinkListNode)// 顶点i的邻接表上有v为入度的结点
    516             {
    517             }
    518             else// 顶点i的邻接表上有v为入度的结点
    519             {
    520                 if(NULL==ptLinkListPreNode)// p指向首元结点
    521                 {
    522                     i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode=ptLinkListNode->ptNext;// 头指针指向下一结点
    523                 }
    524                 else// p1指向p所指结点的前驱
    525                 {
    526                     ptLinkListPreNode->ptNext=ptLinkListNode->ptNext;// 从链表中删除p所指结点
    527                 }
    528                 if(i_ptAdjacencyListGraph->iKind<2)// 有向
    529                 {
    530                     i_ptAdjacencyListGraph->iArcNum--;// 边或弧数-1
    531                     if(i_ptAdjacencyListGraph->iKind==1)// 有向网
    532                     {
    533                         free(ptLinkListNode->tData.pcInfo);// 释放动态生成的权值空间
    534                     }
    535                     else
    536                     {
    537                     }
    538                 }
    539                 else
    540                 {
    541                 }
    542                 free(ptLinkListNode);    
    543             }
    544             for(k=j+1;k<=i_ptAdjacencyListGraph->iVexNum;k++)
    545             {// 对于adjvex域>j的结点,其序号-1(弧指针中指向顶点序号(数组下标)删除后要减一)
    546                 tElement.iAdjvex=k;
    547                 ptLinkListNode=GetLinkListNodePoint(i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode,&tElement,EqualVertex,&ptLinkListPreNode);
    548                 if(NULL==ptLinkListNode)
    549                 {
    550                 }
    551                 else
    552                 {
    553                     ptLinkListNode->tData.iAdjvex--;// 序号-1(因为前移)
    554                 }
    555             }
    556         }
    557         iRet=0;
    558     }
    559     return iRet;
    560 }
    561 
    562 
    563 /*****************************************************************************
    564 -Fuction        : InsertArc
    565 -Description    : 
    566 // 初始条件:图G存在,v(i_ptVertexData)和w(i_ptAdjVertexData)是G中两个顶点
    567 // 操作结果:在G中增添弧<v,w>,若G是无向的,则还增添对称弧<w,v>
    568 -Input            : 
    569 -Output         : 
    570 -Return         : 
    571 * Modify Date      Version         Author           Modification
    572 * -----------------------------------------------
    573 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    574 ******************************************************************************/
    575 static int InsertArc(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData,T_VertexData *i_ptAdjVertexData)
    576 {
    577     int i,j;
    578     int iRet=-1;
    579     T_LinkListElement tElement={0};
    580     i=LocateVertex(i_ptAdjacencyListGraph,i_ptVertexData);// 弧尾或边的序号
    581     j=LocateVertex(i_ptAdjacencyListGraph,i_ptAdjVertexData);// 弧头或边的序号
    582     if(i<0||j<0)
    583     {
    584         iRet=-1;
    585     }
    586     else
    587     {
    588         i_ptAdjacencyListGraph->iArcNum++;
    589         tElement.iAdjvex=j;
    590         tElement.pcInfo=NULL;
    591         if(i_ptAdjacencyListGraph->iKind%2)//// 网
    592         {
    593             tElement.pcInfo=(T_InfoType *)malloc(sizeof(T_InfoType));
    594             printf("请输入弧(边)%s→%s的权值: ",i_ptVertexData->acData,i_ptAdjVertexData->acData);
    595             scanf("%d",&tElement.pcInfo->iWeight);
    596         }
    597         else
    598         {
    599         }
    600         InsertNodeToLinkList(&i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode,1,&tElement);// 将tElement插在弧尾的表头
    601         if(i_ptAdjacencyListGraph->iKind>=2) // 无向,生成另一个表结点
    602         {
    603             tElement.iAdjvex=i; // e.info不变
    604             InsertNodeToLinkList(&i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode,1,&tElement);// 将e插在弧头的表头
    605         }
    606         else
    607         {
    608         }
    609         iRet=0;
    610     }
    611     return iRet;
    612 }
    613 
    614 
    615 /*****************************************************************************
    616 -Fuction        : DeleteArc
    617 -Description    : 
    618 // 初始条件:图G存在,v和w是G中两个顶点
    619 // 操作结果:在G中删除弧<v,w>,若G是无向的,则还删除对称弧<w,v>
    620 -Input            : 
    621 -Output         : 
    622 -Return         : 
    623 * Modify Date      Version         Author           Modification
    624 * -----------------------------------------------
    625 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    626 ******************************************************************************/
    627 static int DeleteArc(T_AdjacencyListGraph *i_ptAdjacencyListGraph,T_VertexData *i_ptVertexData,T_VertexData *i_ptAdjVertexData)
    628 {
    629     int i,j;
    630     int iRet=-1;
    631     T_LinkListElement tElement={0};
    632     i=LocateVertex(i_ptAdjacencyListGraph,i_ptVertexData);// i是顶点v(弧尾)的序号
    633     j=LocateVertex(i_ptAdjacencyListGraph,i_ptAdjVertexData);// j是顶点w(弧头)的序号
    634     if(i<0||j<0)// 没找到待删除的弧
    635     {
    636         iRet=-1;
    637     }
    638     else
    639     {
    640         tElement.iAdjvex=j;
    641         iRet=DeleteElementFromLinkList(i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode,&tElement,EqualVertex);
    642         if(0!=iRet)
    643         {
    644         }
    645         else// 删除成功
    646         {
    647             i_ptAdjacencyListGraph->iArcNum--;// 弧或边数减1
    648             if(i_ptAdjacencyListGraph->iKind%2)//// 网
    649             {
    650                 free(tElement.pcInfo);
    651             }
    652             else{
    653             }
    654             if(i_ptAdjacencyListGraph->iKind>=2) // 无向,删除对称弧<w,v>
    655             {
    656                 tElement.iAdjvex=i;
    657                 iRet=DeleteElementFromLinkList(i_ptAdjacencyListGraph->atVertexList[j].ptFirstArcNode,&tElement,EqualVertex);
    658             }
    659             else
    660             {
    661             }
    662         }
    663     }
    664     return iRet;
    665 }
    666 
    667 
    668 /*****************************************************************************
    669 -Fuction        : DisplayGraph
    670 -Description    : 
    671 // 输出图的邻接矩阵G
    672 -Input            : 
    673 -Output         : 
    674 -Return         : 
    675 * Modify Date      Version         Author           Modification
    676 * -----------------------------------------------
    677 * 2017/06/02      V1.0.0         Yu Weifeng       Created
    678 ******************************************************************************/
    679 static void DisplayGraph(T_AdjacencyListGraph *i_ptAdjacencyListGraph)
    680 {
    681     int i;
    682     T_ArcNode *ptAcrNode=NULL;
    683     switch(i_ptAdjacencyListGraph->iKind)
    684     {
    685         case DG: 
    686             printf("有向图
    ");
    687         break;
    688         case DN: 
    689             printf("有向网
    ");
    690         break;
    691         case UDG: 
    692             printf("无向图
    ");
    693         break;
    694         case UDN: 
    695             printf("无向网
    ");
    696     }
    697     printf("%d个顶点:
    ",i_ptAdjacencyListGraph->iVexNum);
    698     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;++i)
    699     printf("%s ",i_ptAdjacencyListGraph->atVertexList[i].tData.acData);
    700     printf("
    %d条弧(边):
    ",i_ptAdjacencyListGraph->iArcNum);
    701     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;i++)
    702     {
    703         ptAcrNode=i_ptAdjacencyListGraph->atVertexList[i].ptFirstArcNode;
    704         while(NULL!=ptAcrNode)
    705         {
    706             if(i_ptAdjacencyListGraph->iKind<=1||i<ptAcrNode->tData.iAdjvex) // 有向或无向两次中的一次
    707             {
    708                 printf("%s-->%s ",i_ptAdjacencyListGraph->atVertexList[i].tData.acData,i_ptAdjacencyListGraph->atVertexList[ptAcrNode->tData.iAdjvex].tData.acData);
    709                 if(i_ptAdjacencyListGraph->iKind%2) //
    710                 printf(":%d ",ptAcrNode->tData.pcInfo->iWeight);
    711             }
    712             ptAcrNode=ptAcrNode->ptNext;
    713         }
    714         printf("
    ");
    715     }
    716 }
    AdjacencyListGraph.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     AdjacencyListGraph.h
     5 * Description        :     AdjacencyListGraph operation center
     6 * Created            :     2017.05.23.
     7 * Author            :     Yu Weifeng
     8 * Function List         :     
     9 * Last Modified     :     
    10 * History            :     
    11 ******************************************************************************/
    12 #ifndef _ADJACENCY_LIST_GRAPH_H
    13 #define _ADJACENCY_LIST_GRAPH_H
    14 
    15 #define MAX_NAME                5
    16 #define MAX_VERTEX_NUM        20
    17 typedef struct InfoType
    18 {
    19     int iWeight;//权值
    20 }T_InfoType,*PT_InfoType;//最简单的弧的相关信息类型(只有权值)
    21 
    22 typedef struct VertexData
    23 {
    24     char acData[MAX_NAME];
    25 }T_VertexData,*PT_VertexData;
    26 enum GraphKind{DG,DN,UDG,UDN}; // {有向图,有向网,无向图,无向网}
    27 
    28 typedef struct LinkListElement
    29 {
    30     int iAdjvex;// 该弧所指向的顶点的位置,邻接表数组中的位置
    31     T_InfoType *pcInfo;// 网的权值指针
    32 }T_LinkListElement,*PT_LinkListElement;
    33 
    34 typedef struct ArcNode 
    35 {
    36     T_LinkListElement tData;// 除指针以外的部分都属于T_ListElement
    37     struct ArcNode *ptNext;// 指向下一条弧的指针
    38 }T_ArcNode,*PT_ArcNode;// 弧链表结点
    39 
    40 typedef struct VertexNode
    41 {
    42     T_VertexData tData;// 顶点信息
    43     T_ArcNode *ptFirstArcNode;// 第一个表结点的地址,指向第一条依附该顶点的弧的指针
    44 }T_VertexNode,*PT_VertexNode;// 顶点结点
    45 
    46 typedef struct AdjacencyListGraph
    47 {
    48     T_VertexNode atVertexList[MAX_VERTEX_NUM];//邻接表包含所有顶点和弧的信息
    49     int iVexNum;// 图的当前顶点数和弧数
    50     int iArcNum;
    51     int iKind;// 图的种类标志
    52 }T_AdjacencyListGraph,*PT_AdjacencyListGraph;
    53 
    54 
    55 
    56 
    57 #endif
    AdjacencyListGraph.h
     1 8
     2 14
     3 a
     4 b
     5 c
     6 d
     7 e
     8 f
     9 g
    10 h
    11 a b
    12 a c
    13 a e
    14 a f
    15 a g
    16 a h
    17 b d
    18 b e
    19 b h
    20 c g
    21 c h
    22 d h
    23 e f
    24 f g
    AdjacencyListGraph.txt

    2)图的遍历

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     TraverseGraph.c
      5 * Description        :     TraverseGraph operation center
      6 * Created            :     2017.06.12.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 #include "LinkQueue.c"
     17 #include "AdjacencyListGraph.c"
     18 
     19 static void DFSTraverse(T_AdjacencyListGraph *i_ptAdjacencyListGraph);
     20 static void BFSTraverse(T_AdjacencyListGraph *i_ptAdjacencyListGraph);
     21 
     22 #define FALSE    0
     23 #define TRUE         1
     24 
     25 static char g_acVisitedFlag[MAX_VERTEX_NUM]={0};
     26 
     27 /*****************************************************************************
     28 -Fuction        : main
     29 -Description    : main
     30 -Input            : 
     31 -Output         : 
     32 -Return         : 
     33 * Modify Date      Version         Author           Modification
     34 * -----------------------------------------------
     35 * 2017/06/12      V1.0.0         Yu Weifeng       Created
     36 ******************************************************************************/
     37 int main(int argc,char **argv)
     38 {
     39     T_AdjacencyListGraph tGraph;
     40     CreateAdjacencyListGraphFromFile(&tGraph); // 利用数据文件创建无向图
     41     DisplayGraph(&tGraph);// 输出无向图
     42     printf("深度优先搜索的结果:
    ");
     43     DFSTraverse(&tGraph);
     44     printf("广度优先搜索的结果:
    ");
     45     BFSTraverse(&tGraph);
     46     DestroyGraph(&tGraph); // 销毁图g
     47 
     48     return 0;
     49 }
     50 
     51 /*****************************************************************************
     52 -Fuction        : DFS
     53 -Description    : // 从第v(i_iPos)个顶点出发递归地深度优先遍历图
     54 -Input            : 
     55 -Output         : 
     56 -Return         : 
     57 * Modify Date      Version         Author           Modification
     58 * -----------------------------------------------
     59 * 2017/06/12      V1.0.0         Yu Weifeng       Created
     60 ******************************************************************************/
     61 static void DFS(T_AdjacencyListGraph *i_ptAdjacencyListGraph,int i_iVertexPos)
     62 {
     63     int iAdjacencyVertexPos=0;
     64     g_acVisitedFlag[i_iVertexPos]=TRUE;// 设置访问标志为TRUE(已访问)
     65     printf("%s ",i_ptAdjacencyListGraph->atVertexList[i_iVertexPos].tData.acData);// 访问第v个顶点
     66     for(iAdjacencyVertexPos=GetFirstAdjacencyVertex(i_ptAdjacencyListGraph,&i_ptAdjacencyListGraph->atVertexList[i_iVertexPos].tData);
     67           iAdjacencyVertexPos>=0;
     68           iAdjacencyVertexPos=GetNextAdjacencyVertex(i_ptAdjacencyListGraph,&i_ptAdjacencyListGraph->atVertexList[i_iVertexPos].tData,&i_ptAdjacencyListGraph->atVertexList[iAdjacencyVertexPos].tData))
     69     {
     70         if(TRUE==g_acVisitedFlag[iAdjacencyVertexPos])
     71         {
     72         }
     73         else
     74         {
     75             DFS(i_ptAdjacencyListGraph,iAdjacencyVertexPos);// 对v的尚未访问的邻接点w(iAdjacencyVertexPos)递归调用DFS
     76         }
     77     }
     78 }
     79 
     80 /*****************************************************************************
     81 -Fuction        : DFSTraverse
     82 -Description    : // 对图G作深度优先遍历。
     83 -Input            : 
     84 -Output         : 
     85 -Return         : 
     86 * Modify Date      Version         Author           Modification
     87 * -----------------------------------------------
     88 * 2017/06/12      V1.0.0         Yu Weifeng       Created
     89 ******************************************************************************/
     90 static void DFSTraverse(T_AdjacencyListGraph *i_ptAdjacencyListGraph)
     91 {
     92     int i;
     93     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;i++)
     94     {
     95         g_acVisitedFlag[i]=FALSE;// 访问标志数组初始化
     96     }
     97     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;i++)
     98     {
     99         if(TRUE==g_acVisitedFlag[i])
    100         {
    101         }
    102         else
    103         {
    104             DFS(i_ptAdjacencyListGraph,i);// 对尚未访问的顶点调用DFS
    105         }
    106     }
    107     printf("
    ");
    108 }
    109 
    110 /*****************************************************************************
    111 -Fuction        : BFSTraverse
    112 -Description    : //按广度优先非递归遍历图G。使用辅助队列Q和访问标志数组visited
    113 -Input            : 
    114 -Output         : 
    115 -Return         : 
    116 * Modify Date      Version         Author           Modification
    117 * -----------------------------------------------
    118 * 2017/06/12      V1.0.0         Yu Weifeng       Created
    119 ******************************************************************************/
    120 static void BFSTraverse(T_AdjacencyListGraph *i_ptAdjacencyListGraph)
    121 {
    122     int v,u,w;
    123     T_LinkQueue tLinkQueue={0};
    124     T_QueueDataElement tEnterElement={0};    
    125     T_QueueDataElement tExitElement={0};
    126     for(v=0;v<i_ptAdjacencyListGraph->iVexNum;v++)
    127     {
    128         g_acVisitedFlag[v]=FALSE;// 访问标志数组初始化
    129     }
    130     InitLinkQueue(&tLinkQueue);
    131     for(v=0;v<i_ptAdjacencyListGraph->iVexNum;v++)// 如果是连通图,只v=0就遍历全图
    132     {
    133         if(TRUE==g_acVisitedFlag[v])
    134         {
    135         }
    136         else// v尚未访问
    137         {
    138             g_acVisitedFlag[v]=TRUE;
    139             printf("%s ",i_ptAdjacencyListGraph->atVertexList[v].tData.acData);
    140             tEnterElement.iData=v;
    141             EnterLinkQueue(&tLinkQueue,tEnterElement);// v入队列
    142             while(0!=IsLinkQueueEmpty(&tLinkQueue))// 队列不空
    143             {
    144                 ExitLinkQueue(&tLinkQueue,&tExitElement);// 出队用于访问其各个邻接点    
    145                 u=tExitElement.iData;
    146                 for(w=GetFirstAdjacencyVertex(i_ptAdjacencyListGraph,&i_ptAdjacencyListGraph->atVertexList[u].tData);
    147                       w>=0;
    148                       w=GetNextAdjacencyVertex(i_ptAdjacencyListGraph,&i_ptAdjacencyListGraph->atVertexList[u].tData,&i_ptAdjacencyListGraph->atVertexList[w].tData))
    149                 {
    150                       if(TRUE==g_acVisitedFlag[w])
    151                       {
    152                       }
    153                       else// w为u的尚未访问的邻接顶点
    154                       {
    155                           g_acVisitedFlag[w]=TRUE;
    156                           printf("%s ",i_ptAdjacencyListGraph->atVertexList[w].tData.acData);
    157                           tEnterElement.iData=w;
    158                           EnterLinkQueue(&tLinkQueue,tEnterElement);// w入队,当本层邻接点访问完后,由此可按顺序访问下一层邻接点
    159                       }          
    160                 }
    161             }
    162         }
    163     }
    164     printf("
    ");
    165 }
    TraverseGraph.c

    二、算法

    1.查找

    1)顺序查找

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     SequenceSearch.c
      5 * Description        :     SequenceSearch operation center
      6 * Created            :     2017.06.14.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 #define ELEMENT_NUM    3
     18 
     19 #define Key dwNumber    // 定义关键字为准考证号
     20 typedef unsigned int KeyType;// 设关键字域为整型
     21 
     22 typedef struct SeqTableElement
     23 {
     24     unsigned int dwNumber;
     25     char strName[9]; // 姓名(4个汉字加1个串结束标志)
     26 }T_SeqTableElement,*PT_SeqTableElement;
     27 
     28 
     29 typedef struct SeqTable
     30 {
     31     T_SeqTableElement *ptElement;
     32     int iLength;
     33 }T_SeqTable,*PT_SeqTable;
     34 
     35 static void CreateSeqTable(T_SeqTableElement i_atElement[],int i_iNum,T_SeqTable *o_ptSeqTable);
     36 static int SequenceSearch(T_SeqTable *i_ptSeqTable,KeyType i_Key);
     37 static void TraverseSeqTable(T_SeqTable *i_ptSeqTable);
     38 static void DestroySeqTable(T_SeqTable *i_ptSeqTable);
     39 
     40 /*****************************************************************************
     41 -Fuction        : main
     42 -Description    : main
     43 -Input            : 
     44 -Output         : 
     45 -Return         : 
     46 * Modify Date      Version         Author           Modification
     47 * -----------------------------------------------
     48 * 2017/06/14      V1.0.0         Yu Weifeng       Created
     49 ******************************************************************************/
     50 int main(int argc,char **argv)
     51 {
     52     int i;
     53     KeyType    KeyElement=0;
     54     T_SeqTableElement atElement[ELEMENT_NUM]={{123456,"LiMing"},{123467,"XiaoMing"},{123477,"LiHua"}};
     55     T_SeqTable tSeqTable={0};
     56     CreateSeqTable(atElement,ELEMENT_NUM,&tSeqTable);
     57     TraverseSeqTable(&tSeqTable);
     58     printf("请输入待查找人的考号: ");
     59     scanf("%d",&KeyElement);
     60     i=SequenceSearch(&tSeqTable,KeyElement); // 顺序查找
     61     if(i)
     62     printf("%8d%8s
    ",tSeqTable.ptElement[i].dwNumber,tSeqTable.ptElement[i].strName);
     63     else
     64     printf("没找到
    ");
     65     DestroySeqTable(&tSeqTable);
     66 
     67     return 0;
     68 }
     69 
     70 
     71 
     72 /*****************************************************************************
     73 -Fuction        : CreateSeqTable
     74 -Description    : 
     75 // 操作结果:由含n个数据元素的数组r构造静态顺序查找表ST
     76 
     77 -Input            : 
     78 -Output         : 
     79 -Return         : 
     80 * Modify Date      Version         Author           Modification
     81 * -----------------------------------------------
     82 * 2017/06/14      V1.0.0         Yu Weifeng       Created
     83 ******************************************************************************/
     84 static void CreateSeqTable(T_SeqTableElement i_atElement[],int i_iNum,T_SeqTable *o_ptSeqTable)
     85 {
     86     int i;
     87     //与malloc的区别,calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
     88     o_ptSeqTable->ptElement=(T_SeqTableElement *)calloc(i_iNum+1,sizeof(T_SeqTableElement));// 动态生成n+1个数据元素空间(0号单元不用)
     89     if(NULL==o_ptSeqTable->ptElement)
     90     {
     91         printf("CreareSeqTable err,calloc fail
    ");
     92     }
     93     else
     94     {
     95         for(i=1;i<=i_iNum;i++)
     96         {
     97             memcpy(&o_ptSeqTable->ptElement[i],&i_atElement[i-1],sizeof(T_SeqTableElement));
     98         }
     99         o_ptSeqTable->iLength=i_iNum;
    100     }
    101 }
    102 
    103 /*****************************************************************************
    104 -Fuction        : SequenceSearch
    105 -Description    : 
    106 // 在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则返回
    107 // 该元素在表中的位置;否则返回0。
    108 -Input            : 
    109 -Output         : 
    110 -Return         : 
    111 * Modify Date      Version         Author           Modification
    112 * -----------------------------------------------
    113 * 2017/06/14      V1.0.0         Yu Weifeng       Created
    114 ******************************************************************************/
    115 static int SequenceSearch(T_SeqTable *i_ptSeqTable,KeyType i_Key)
    116 {
    117     int i=0;
    118     i_ptSeqTable->ptElement[0].Key=i_Key;// 哨兵
    119     for(i=i_ptSeqTable->iLength;i_Key!=i_ptSeqTable->ptElement[i].Key;i--);// 从后往前找
    120     return i;// 找不到时,i为0
    121 }
    122 
    123 /*****************************************************************************
    124 -Fuction        : TraverseSeqTable
    125 -Description    : TraverseSeqTable
    126 -Input            : 
    127 -Output         : 
    128 -Return         : 
    129 * Modify Date      Version         Author           Modification
    130 * -----------------------------------------------
    131 * 2017/06/14      V1.0.0         Yu Weifeng       Created
    132 ******************************************************************************/
    133 static void TraverseSeqTable(T_SeqTable *i_ptSeqTable)
    134 {
    135     int i=0;
    136     for(i=1;i<=i_ptSeqTable->iLength;i++)
    137     {
    138         printf("%8d%8s
    ",i_ptSeqTable->ptElement[i].dwNumber,i_ptSeqTable->ptElement[i].strName);
    139     }
    140 }
    141 
    142 /*****************************************************************************
    143 -Fuction        : DestroySeqTable
    144 -Description    : DestroySeqTable
    145 -Input            : 
    146 -Output         : 
    147 -Return         : 
    148 * Modify Date      Version         Author           Modification
    149 * -----------------------------------------------
    150 * 2017/06/14      V1.0.0         Yu Weifeng       Created
    151 ******************************************************************************/
    152 static void DestroySeqTable(T_SeqTable *i_ptSeqTable)
    153 {
    154     free(i_ptSeqTable->ptElement);
    155     i_ptSeqTable->ptElement=NULL;
    156     i_ptSeqTable->iLength=0;
    157 }
    SequenceSearch.c

    2)折半查找

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     BiSearch.c
      5 * Description        :     BiSearch operation center
      6 * Created            :     2017.06.14.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 #define ELEMENT_NUM    11
     18 
     19 typedef  int KeyType;// 设关键字域为整型
     20 
     21 typedef struct SeqTableElement
     22 {
     23     KeyType key;    // 仅有关键字域
     24 }T_SeqTableElement,*PT_SeqTableElement;
     25 
     26 typedef struct SeqTable
     27 {
     28     T_SeqTableElement *ptElement;
     29     int iLength;
     30 }T_SeqTable,*PT_SeqTable;
     31 
     32 static void CreateOrderSeqTable(T_SeqTableElement i_atElement[],int i_iNum,T_SeqTable *o_ptSeqTable);
     33 static void TraverseOrderSeqTable(T_SeqTable *i_ptSeqTable);
     34 static int BiSearch(T_SeqTable *i_ptSeqTable,KeyType i_Key);
     35 static void DestroyOrderSeqTable(T_SeqTable *i_ptSeqTable);
     36 /*****************************************************************************
     37 -Fuction        : main
     38 -Description    : main
     39 -Input            : 
     40 -Output         : 
     41 -Return         : 
     42 * Modify Date      Version         Author           Modification
     43 * -----------------------------------------------
     44 * 2017/06/14      V1.0.0         Yu Weifeng       Created
     45 ******************************************************************************/
     46 int main(int argc,char **argv)
     47 {
     48     int i;
     49     KeyType    KeyElement=0;
     50     T_SeqTableElement atElement[ELEMENT_NUM]={5,13,19,21,37,56,64,75,80,88,92};
     51     T_SeqTable tSeqTable={0};
     52     CreateOrderSeqTable(atElement,ELEMENT_NUM,&tSeqTable);
     53     TraverseOrderSeqTable(&tSeqTable);
     54     printf("请输入待查找值的关键字: ");
     55     scanf("%d",&KeyElement);
     56     i=BiSearch(&tSeqTable,KeyElement); // 折半查找有序表
     57     if(i)
     58     printf("%d 是第%d个记录的关键字
    ",tSeqTable.ptElement[i].key,i);
     59     else
     60     printf("没找到
    ");
     61     DestroyOrderSeqTable(&tSeqTable);
     62 
     63     return 0;
     64 }
     65 
     66 
     67 
     68 /*****************************************************************************
     69 -Fuction        : CreateSeqTable
     70 -Description    : 
     71 // 操作结果:由含n个数据元素的数组r构造静态顺序查找表ST
     72 
     73 -Input            : 
     74 -Output         : 
     75 -Return         : 
     76 * Modify Date      Version         Author           Modification
     77 * -----------------------------------------------
     78 * 2017/06/14      V1.0.0         Yu Weifeng       Created
     79 ******************************************************************************/
     80 static void CreateOrderSeqTable(T_SeqTableElement i_atElement[],int i_iNum,T_SeqTable *o_ptSeqTable)
     81 {
     82     int i;
     83     //与malloc的区别,calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
     84     o_ptSeqTable->ptElement=(T_SeqTableElement *)calloc(i_iNum+1,sizeof(T_SeqTableElement));// 动态生成n+1个数据元素空间(0号单元不用)
     85     if(NULL==o_ptSeqTable->ptElement)
     86     {
     87         printf("CreareSeqTable err,calloc fail
    ");
     88     }
     89     else
     90     {
     91         for(i=1;i<=i_iNum;i++)
     92         {//数组第1个位置即序号0的位置不存放,因为位置从1开始,同时方便查找返回值处理
     93             memcpy(&o_ptSeqTable->ptElement[i],&i_atElement[i-1],sizeof(T_SeqTableElement));
     94         }
     95         //memcpy(o_ptSeqTable->ptElement,i_atElement,sizeof(i_atElement));//传入的是地址这样拷贝不行
     96         o_ptSeqTable->iLength=i_iNum;
     97     }
     98 }
     99 
    100 /*****************************************************************************
    101 -Fuction        : BiSearch
    102 -Description    : 
    103 // 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则返回
    104 // 该元素在表中的位置;否则返回0。
    105 -Input            : 
    106 -Output         : 
    107 -Return         : 
    108 * Modify Date      Version         Author           Modification
    109 * -----------------------------------------------
    110 * 2017/06/14      V1.0.0         Yu Weifeng       Created
    111 ******************************************************************************/
    112 static int BiSearch(T_SeqTable *i_ptOrderSeqTable,KeyType i_Key)
    113 {
    114     int iPos=0;
    115     int iLow,iHigh,iMid;
    116     iLow=1;
    117     iHigh=i_ptOrderSeqTable->iLength;
    118     while(iLow<=iHigh)
    119     {
    120         iMid=(iLow+iHigh)/2;
    121         if(i_Key==i_ptOrderSeqTable->ptElement[iMid].key)
    122         {
    123             iPos=iMid;
    124             break;
    125         }
    126         else if(i_Key<i_ptOrderSeqTable->ptElement[iMid].key)
    127         {
    128             iHigh=iMid-1;
    129         }
    130         else
    131         {
    132             iLow=iMid+1;
    133         }
    134     }
    135     return iPos;
    136 }
    137 
    138 /*****************************************************************************
    139 -Fuction        : TraverseOrderSeqTable
    140 -Description    : TraverseOrderSeqTable
    141 -Input            : 
    142 -Output         : 
    143 -Return         : 
    144 * Modify Date      Version         Author           Modification
    145 * -----------------------------------------------
    146 * 2017/06/14      V1.0.0         Yu Weifeng       Created
    147 ******************************************************************************/
    148 static void TraverseOrderSeqTable(T_SeqTable *i_ptSeqTable)
    149 {
    150     int i=0;
    151     for(i=1;i<=i_ptSeqTable->iLength;i++)
    152     {
    153         printf("%d ",i_ptSeqTable->ptElement[i].key);
    154     }
    155     printf("
    ");
    156 }
    157 
    158 /*****************************************************************************
    159 -Fuction        : DestroyOrderSeqTable
    160 -Description    : DestroyOrderSeqTable
    161 -Input            : 
    162 -Output         : 
    163 -Return         : 
    164 * Modify Date      Version         Author           Modification
    165 * -----------------------------------------------
    166 * 2017/06/14      V1.0.0         Yu Weifeng       Created
    167 ******************************************************************************/
    168 static void DestroyOrderSeqTable(T_SeqTable *i_ptSeqTable)
    169 {
    170     free(i_ptSeqTable->ptElement);
    171     i_ptSeqTable->ptElement=NULL;
    172     i_ptSeqTable->iLength=0;
    173 }
    BiSearch.c

    3)哈希表的查找

    2.排序

    1)插入排序

    I、直接插入排序

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     InsertSort.c
      5 * Description        :     InsertSort operation center
      6 * Created            :     2017.06.15.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 
     18 #define RECORD_SEQ_LIST_MAX_LEN        20
     19 #define RECORD_NUMBER                8
     20 
     21 typedef int KeyType;
     22 
     23 typedef struct RecordType
     24 {
     25     KeyType Key;
     26     int OtherInfo;
     27 }T_RecordType,*PT_RecordType;
     28 
     29 typedef struct RecordSeqList
     30 {
     31     T_RecordType atRecord[RECORD_SEQ_LIST_MAX_LEN+1];// r[0]闲置或用作哨兵单元
     32     int iLength;
     33 }T_RecordSeqList,*PT_RecordSeqList;
     34 
     35 static void TraverseRecordSeqList(T_RecordSeqList *i_ptRecordSeqList);
     36 static void InsertSort(T_RecordSeqList *i_ptRecordSeqList);
     37 
     38 /*****************************************************************************
     39 -Fuction        : main
     40 -Description    : main
     41 -Input            : 
     42 -Output         : 
     43 -Return         : 
     44 * Modify Date      Version         Author           Modification
     45 * -----------------------------------------------
     46 * 2017/06/15      V1.0.0         Yu Weifeng       Created
     47 ******************************************************************************/
     48 int main(int argc,char **argv)
     49 {
     50     T_RecordType atRecord[RECORD_NUMBER]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
     51     T_RecordSeqList tSeqList1, tSeqList2, tSeqList3;
     52     int i;
     53     for(i=0;i<RECORD_NUMBER;i++) // 给l1.r赋值
     54         tSeqList1.atRecord[i+1]=atRecord[i];
     55     tSeqList1.iLength=RECORD_NUMBER;
     56     tSeqList3=tSeqList2=tSeqList1; // 复制顺序表l2、l3与l1相同
     57     printf("排序前:
    ");
     58     TraverseRecordSeqList(&tSeqList1);
     59     InsertSort(&tSeqList1);
     60     printf("直接插入排序后:
    ");
     61     TraverseRecordSeqList(&tSeqList1);
     62 
     63     return 0;
     64 }
     65 
     66 /*****************************************************************************
     67 -Fuction        : InsertSort
     68 -Description    : // 对顺序表L作直接插入排序
     69 -Input            : 
     70 -Output         : 
     71 -Return         : 
     72 * Modify Date      Version         Author           Modification
     73 * -----------------------------------------------
     74 * 2017/06/15      V1.0.0         Yu Weifeng       Created
     75 ******************************************************************************/
     76 static void InsertSort(T_RecordSeqList *i_ptRecordSeqList)
     77 {
     78     int i,j;
     79     for(i=2;i<=i_ptRecordSeqList->iLength;i++)
     80     {
     81         if(i_ptRecordSeqList->atRecord[i].Key<i_ptRecordSeqList->atRecord[i-1].Key)// "<",需将L.r[i]插入有序子表
     82         {
     83             memcpy(&i_ptRecordSeqList->atRecord[0],&i_ptRecordSeqList->atRecord[i],sizeof(T_RecordType));// 复制为哨兵
     84             for(j=i-1;(i_ptRecordSeqList->atRecord[0].Key<i_ptRecordSeqList->atRecord[j].Key);j--)
     85             {// 记录后移
     86                 memcpy(&i_ptRecordSeqList->atRecord[j+1],&i_ptRecordSeqList->atRecord[j],sizeof(T_RecordType));// 记录后移
     87             }
     88             memcpy(&i_ptRecordSeqList->atRecord[j+1],&i_ptRecordSeqList->atRecord[0],sizeof(T_RecordType));// 插入到正确位置
     89         }
     90         else
     91         {
     92         }
     93     }
     94 }
     95 
     96 /*****************************************************************************
     97 -Fuction        : TraverseRecordSeqList
     98 -Description    : TraverseRecordSeqList
     99 -Input            : 
    100 -Output         : 
    101 -Return         : 
    102 * Modify Date      Version         Author           Modification
    103 * -----------------------------------------------
    104 * 2017/06/15      V1.0.0         Yu Weifeng       Created
    105 ******************************************************************************/
    106 static void TraverseRecordSeqList(T_RecordSeqList *i_ptRecordSeqList)
    107 {
    108     int i;
    109     for(i=1;i<=i_ptRecordSeqList->iLength;i++)
    110     {
    111         printf("(%d,%d)",i_ptRecordSeqList->atRecord[i].Key,i_ptRecordSeqList->atRecord[i].OtherInfo);
    112     }
    113     printf("
    ");
    114 }
    InsertSort.c

    II、折半插入排序

     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     BiInsertSort.c
     5 * Description        :     BiInsertSort operation center
     6 * Created            :     2017.06.16.
     7 * Author            :     Yu Weifeng
     8 * Function List         :     
     9 * Last Modified     :     
    10 * History            :     
    11 ******************************************************************************/
    12 #include"stdio.h"
    13 #include"malloc.h"
    14 #include"stdlib.h"
    15 #include"string.h"
    16 
    17 
    18 
    19 
    20 /*****************************************************************************
    21 -Fuction        : main
    22 -Description    : main
    23 -Input            : 
    24 -Output         : 
    25 -Return         : 
    26 * Modify Date      Version         Author           Modification
    27 * -----------------------------------------------
    28 * 2017/06/15      V1.0.0         Yu Weifeng       Created
    29 ******************************************************************************/
    30 int main(int argc,char **argv)
    31 {
    32     T_RecordType atRecord[RECORD_NUMBER]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
    33     T_RecordSeqList tSeqList1, tSeqList2, tSeqList3;
    34     int i;
    35     for(i=0;i<RECORD_NUMBER;i++) // 给l1.r赋值
    36         tSeqList1.atRecord[i+1]=atRecord[i];
    37     tSeqList1.iLength=RECORD_NUMBER;
    38     tSeqList3=tSeqList2=tSeqList1; // 复制顺序表l2、l3与l1相同
    39     printf("排序前:
    ");
    40     TraverseRecordSeqList(&tSeqList1);
    41     MergeSort(&tSeqList1);
    42     printf("折半插入排序后:
    ");
    43     TraverseRecordSeqList(&tSeqList1);
    44 
    45     return 0;
    46 }
    BiInsertSort.c

    III、希尔排序

    2)交换排序

    I、冒泡排序

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     BubbleSort.java
      5 * Description        :     BubbleSort operation center
      6 * Created            :     2017.06.16.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 
     13 
     14 
     15 
     16 import java.util.Arrays; 
     17 
     18 
     19 /*****************************************************************************
     20 -Class            : BubbleSort
     21 -Description    : main
     22 * Modify Date      Version         Author           Modification
     23 * -----------------------------------------------
     24 * 2017/06/19      V1.0.0         Yu Weifeng       Created
     25 ******************************************************************************/
     26 public class BubbleSort
     27 {
     28     public static final int ARRAY_LEN=9;
     29     BubbleSortClass pBuddleSort;
     30     /*****************************************************************************
     31     -Fuction        : main
     32     -Description    : main
     33     -Input            : 
     34     -Output         : 
     35     -Return         : 
     36     * Modify Date      Version         Author           Modification
     37     * -----------------------------------------------
     38     * 2017/06/19      V1.0.0         Yu Weifeng       Created
     39     ******************************************************************************/
     40     public static void main(String args[]){
     41         int aiSortBuf[] = {3,4,1,2,6,7,8,9,5};//constant Init must be in define
     42         BubbleSortClass mBuddleSort = new BubbleSortClass(aiSortBuf,ARRAY_LEN);
     43         System.out.println("oneCmpOneSort");
     44         mBuddleSort.oneCmpOneSort();
     45         mBuddleSort.printInfo();
     46         System.out.println("oneCmpAllSort");
     47         mBuddleSort.oneCmpAllSort();
     48         mBuddleSort.printInfo();
     49         System.out.println("apiSort");
     50         mBuddleSort.apiSort();
     51         mBuddleSort.printInfo();
     52     }
     53 }
     54 
     55 /*****************************************************************************
     56 -Class            : BubbleSortClass
     57 -Description    : oneCmpOneSort
     58 * Modify Date      Version         Author           Modification
     59 * -----------------------------------------------
     60 * 2017/06/19      V1.0.0         Yu Weifeng       Created
     61 ******************************************************************************/
     62  class BubbleSortClass
     63  {
     64      private int[] piSortBuf;
     65     private int iLen;
     66     /*****************************************************************************
     67     -Fuction        : BubbleSortClass
     68     -Description    : BubbleSortClass
     69     -Input            : 
     70     -Output         : 
     71     * Modify Date      Version         Author           Modification
     72     * -----------------------------------------------
     73     * 2017/06/19      V1.0.0         Yu Weifeng       Created
     74     ******************************************************************************/
     75     public BubbleSortClass(int[] i_piBuf,int i_iLen)
     76     {
     77         int i;
     78         //aiSortBuf=Arrays.copyOf(i_piBuf,i_iLen);// Or use this to copy
     79         piSortBuf=new int[i_iLen];
     80         for(i=0;i<i_iLen;i++){
     81             piSortBuf[i]=i_piBuf[i];
     82         }
     83         iLen=i_iLen;
     84     }
     85     /*****************************************************************************
     86     -Fuction        : oneCmpOneSort
     87     -Description    : oneCmpOneSort
     88     -Input            : 
     89     -Output         : 
     90     -Return         : 
     91     * Modify Date      Version         Author           Modification
     92     * -----------------------------------------------
     93     * 2017/06/19      V1.0.0         Yu Weifeng       Created
     94     ******************************************************************************/
     95     public void oneCmpOneSort()
     96     {
     97         int i,j;
     98         int iBufSwap;
     99         for(i=0;i<iLen-1;i++){//all trips
    100             for(j=0;j<iLen-i-1;j++){//cmp times a trip
    101                 if(piSortBuf[j]>piSortBuf[j+1]){
    102                     iBufSwap=piSortBuf[j+1];
    103                     piSortBuf[j+1]=piSortBuf[j];
    104                     piSortBuf[j]=iBufSwap;
    105                 }
    106                 else{
    107                 }
    108             }
    109         }
    110     }
    111     /*****************************************************************************
    112     -Fuction        : oneCmpAllSort
    113     -Description    : oneCmpAllSort
    114     -Input            : 
    115     -Output         : 
    116     * Modify Date      Version         Author           Modification
    117     * -----------------------------------------------
    118     * 2017/06/19      V1.0.0         Yu Weifeng       Created
    119     ******************************************************************************/
    120     public void oneCmpAllSort()
    121     {
    122         int i,j;
    123         int iBufSwap;
    124         for(i=0;i<iLen-1;i++){//all trips
    125             for(j=0;j<iLen-i-1;j++){//cmp times a trip
    126                 if(piSortBuf[i]>piSortBuf[j+i+1]){
    127                     iBufSwap=piSortBuf[j+i+1];
    128                     piSortBuf[j+i+1]=piSortBuf[i];
    129                     piSortBuf[i]=iBufSwap;
    130                 }
    131                 else{
    132                 }
    133             }
    134         }
    135     }
    136     /*****************************************************************************
    137     -Fuction        : oneCmpAllSort
    138     -Description    : oneCmpAllSort
    139     -Input            : 
    140     -Output         : 
    141     * Modify Date      Version         Author           Modification
    142     * -----------------------------------------------
    143     * 2017/06/19      V1.0.0         Yu Weifeng       Created
    144     ******************************************************************************/
    145     public void apiSort()
    146     {
    147         Arrays.sort(piSortBuf);
    148     }
    149     /*****************************************************************************
    150     -Fuction        : oneCmpAllSort
    151     -Description    : oneCmpAllSort
    152     -Input            : 
    153     -Output         : 
    154     * Modify Date      Version         Author           Modification
    155     * -----------------------------------------------
    156     * 2017/06/19      V1.0.0         Yu Weifeng       Created
    157     ******************************************************************************/
    158     public void printInfo()
    159     {
    160         int i;
    161         for(i=0;i<iLen;i++){
    162             System.out.println(piSortBuf[i]);
    163         }
    164         //System.out.println(Arrays.toString(aiSortBuf));//Or use this to print
    165     }
    166 }
    167     
    BubbleSort.java

    II、快速排序

    3)选择排序

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     SelectSort.c
      5 * Description        :     SelectSort operation center
      6 * Created            :     2017.06.15.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 
     18 #define RECORD_SEQ_LIST_MAX_LEN        20
     19 #define RECORD_NUMBER                8
     20 
     21 typedef int KeyType;
     22 
     23 typedef struct RecordType
     24 {
     25     KeyType Key;
     26     int OtherInfo;
     27 }T_RecordType,*PT_RecordType;
     28 
     29 typedef struct RecordSeqList
     30 {
     31     T_RecordType atRecord[RECORD_SEQ_LIST_MAX_LEN+1];// r[0]闲置或用作哨兵单元
     32     int iLength;
     33 }T_RecordSeqList,*PT_RecordSeqList;
     34 
     35 static int SelectMinKey(T_RecordSeqList *i_ptRecordSeqList,int i_iPos);
     36 
     37 static void TraverseRecordSeqList(T_RecordSeqList *i_ptRecordSeqList);
     38 static void SelectSort(T_RecordSeqList *i_ptRecordSeqList);
     39 
     40 
     41 /*****************************************************************************
     42 -Fuction        : main
     43 -Description    : main
     44 -Input            : 
     45 -Output         : 
     46 -Return         : 
     47 * Modify Date      Version         Author           Modification
     48 * -----------------------------------------------
     49 * 2017/06/15      V1.0.0         Yu Weifeng       Created
     50 ******************************************************************************/
     51 int main(int argc,char **argv)
     52 {
     53     T_RecordType atRecord[RECORD_NUMBER]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
     54     T_RecordSeqList tSeqList1, tSeqList2, tSeqList3;
     55     int i;
     56     for(i=0;i<RECORD_NUMBER;i++) // 给l1.r赋值
     57         tSeqList1.atRecord[i+1]=atRecord[i];
     58     tSeqList1.iLength=RECORD_NUMBER;
     59     tSeqList3=tSeqList2=tSeqList1; // 复制顺序表l2、l3与l1相同
     60     printf("排序前:
    ");
     61     TraverseRecordSeqList(&tSeqList1);
     62     SelectSort(&tSeqList1);
     63     printf("简单选择排序后:
    ");
     64     TraverseRecordSeqList(&tSeqList1);
     65 
     66     return 0;
     67 }
     68 
     69 /*****************************************************************************
     70 -Fuction        : SelectSort
     71 -Description    : // 对顺序表L作简单选择排序
     72 -Input            : 
     73 -Output         : 
     74 -Return         : 
     75 * Modify Date      Version         Author           Modification
     76 * -----------------------------------------------
     77 * 2017/06/15      V1.0.0         Yu Weifeng       Created
     78 ******************************************************************************/
     79 static void SelectSort(T_RecordSeqList *i_ptRecordSeqList)
     80 {
     81     int i,j;
     82     T_RecordType tRecord={0};
     83     for(i=1;i<i_ptRecordSeqList->iLength;i++)
     84     {// 选择第i小的记录,并交换到位(选择第i小的放第i位)
     85         j=SelectMinKey(i_ptRecordSeqList,i);// 在L.r[i..L.length]中选择key最小的记录
     86         if(i!=j)
     87         {// 与第i个记录交换
     88             tRecord=i_ptRecordSeqList->atRecord[i];
     89             i_ptRecordSeqList->atRecord[i]=i_ptRecordSeqList->atRecord[j];
     90             i_ptRecordSeqList->atRecord[j]=tRecord;
     91         }
     92         else
     93         {
     94         }
     95     }
     96 }
     97 
     98 /*****************************************************************************
     99 -Fuction        : SelectMinKey
    100 -Description    : // 返回在L.r[i..L.length]中key最小的记录的序号
    101 -Input            : 
    102 -Output         : 
    103 -Return         : 
    104 * Modify Date      Version         Author           Modification
    105 * -----------------------------------------------
    106 * 2017/06/15      V1.0.0         Yu Weifeng       Created
    107 ******************************************************************************/
    108 static int SelectMinKey(T_RecordSeqList *i_ptRecordSeqList,int i_iPos)
    109 {
    110     int i,j;
    111     KeyType tMinKey={0};
    112     j=i_iPos;// 设第i_iPos个为最小
    113     tMinKey=i_ptRecordSeqList->atRecord[i_iPos].Key;
    114     for(i=i_iPos+1;i<=i_ptRecordSeqList->iLength;i++)
    115     {
    116         if(i_ptRecordSeqList->atRecord[i].Key<tMinKey)// 找到更小的
    117         {
    118             j=i;
    119             tMinKey=i_ptRecordSeqList->atRecord[i].Key;
    120         }
    121         else
    122         {
    123         }
    124     }
    125     return j;
    126 }
    127 
    128 /*****************************************************************************
    129 -Fuction        : TraverseRecordSeqList
    130 -Description    : TraverseRecordSeqList
    131 -Input            : 
    132 -Output         : 
    133 -Return         : 
    134 * Modify Date      Version         Author           Modification
    135 * -----------------------------------------------
    136 * 2017/06/15      V1.0.0         Yu Weifeng       Created
    137 ******************************************************************************/
    138 static void TraverseRecordSeqList(T_RecordSeqList *i_ptRecordSeqList)
    139 {
    140     int i;
    141     for(i=1;i<=i_ptRecordSeqList->iLength;i++)
    142     {
    143         printf("(%d,%d)",i_ptRecordSeqList->atRecord[i].Key,i_ptRecordSeqList->atRecord[i].OtherInfo);
    144     }
    145     printf("
    ");
    146 }
    SelectSort.c

    4)归并排序

      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     MergeSort.c
      5 * Description        :     MergeSort operation center
      6 * Created            :     2017.06.15.
      7 * Author            :     Yu Weifeng
      8 * Function List         :     
      9 * Last Modified     :     
     10 * History            :     
     11 ******************************************************************************/
     12 #include"stdio.h"
     13 #include"malloc.h"
     14 #include"stdlib.h"
     15 #include"string.h"
     16 
     17 
     18 
     19 #define SEQ_LIST_RECORD_MAX_LEN        20
     20 #define RECORD_NUMBER                8
     21 
     22 typedef int KeyType;
     23 
     24 typedef struct RecordType
     25 {
     26     KeyType Key;
     27     int OtherInfo;
     28 }T_RecordType,*PT_RecordType;
     29 
     30 typedef struct RecordSeqList
     31 {
     32     T_RecordType atRecord[SEQ_LIST_RECORD_MAX_LEN+1];// r[0]闲置或用作哨兵单元
     33     int iLength;
     34 }T_RecordSeqList,*PT_RecordSeqList;
     35 static void Merge(T_RecordType i_atSrcRecord[],T_RecordType o_atDstRecord[],int i_iLow,int i_iMid,int i_iHigh);
     36 static void MSort(T_RecordType i_atSrcRecord[],T_RecordType o_atDstRecord[],int i_iLow, int i_iHigh);
     37 
     38 
     39 
     40 static void MergeSort(T_RecordSeqList *i_ptRecordSeqList);
     41 static void TraverseRecordSeqList(T_RecordSeqList *i_ptRecordSeqList);
     42 
     43 /*****************************************************************************
     44 -Fuction        : main
     45 -Description    : main
     46 -Input            : 
     47 -Output         : 
     48 -Return         : 
     49 * Modify Date      Version         Author           Modification
     50 * -----------------------------------------------
     51 * 2017/06/15      V1.0.0         Yu Weifeng       Created
     52 ******************************************************************************/
     53 int main(int argc,char **argv)
     54 {
     55     T_RecordType atRecord[RECORD_NUMBER]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
     56     T_RecordSeqList tSeqList1, tSeqList2, tSeqList3;
     57     int i;
     58     for(i=0;i<RECORD_NUMBER;i++) // 给l1.r赋值
     59         tSeqList1.atRecord[i+1]=atRecord[i];
     60     tSeqList1.iLength=RECORD_NUMBER;
     61     tSeqList3=tSeqList2=tSeqList1; // 复制顺序表l2、l3与l1相同
     62     printf("排序前:
    ");
     63     TraverseRecordSeqList(&tSeqList1);
     64     MergeSort(&tSeqList1);
     65     printf("归并排序后:
    ");
     66     TraverseRecordSeqList(&tSeqList1);
     67 
     68     return 0;
     69 }
     70 
     71 /*****************************************************************************
     72 -Fuction        : MergeSort
     73 -Description    : 对顺序表L作归并排序
     74 -Input            : 
     75 -Output         : 
     76 -Return         : 
     77 * Modify Date      Version         Author           Modification
     78 * -----------------------------------------------
     79 * 2017/06/15      V1.0.0         Yu Weifeng       Created
     80 ******************************************************************************/
     81 static void MergeSort(T_RecordSeqList *i_ptRecordSeqList)
     82 {
     83     MSort(i_ptRecordSeqList->atRecord,i_ptRecordSeqList->atRecord,1,i_ptRecordSeqList->iLength);//0不放元素所以传1(从1开始
     84 }
     85 
     86 /*****************************************************************************
     87 -Fuction        : MSort
     88 -Description    : // 将i_atSrcRecord[s(i_iLow)..t(i_iHigh)]归并排序为o_atDstRecord[s..t]。
     89 整个序列分为左右两半且要都是有序的,然后再归并
     90 左半部分又分为两半且要都是有序的,然后再归并
     91 右半部分又分为两半且要都是有序的,然后再归并(分割的子问题有和父问题是一样的处理考虑用递归)
     92 (递归中先前半部分(左边)变为有序,再后半部分(右边)变为有序)
     93 直到左右两半都只有一个元素即有序了再向上归并,
     94 -Input            : 
     95 -Output         : 
     96 -Return         : 
     97 * Modify Date      Version         Author           Modification
     98 * -----------------------------------------------
     99 * 2017/06/15      V1.0.0         Yu Weifeng       Created
    100 ******************************************************************************/
    101 static void MSort(T_RecordType i_atSrcRecord[],T_RecordType o_atDstRecord[],int i_iLow, int i_iHigh)
    102 {
    103     int iMid;
    104     T_RecordType atRecord[SEQ_LIST_RECORD_MAX_LEN+1]={0};
    105     if(i_iLow==i_iHigh)
    106     {
    107         o_atDstRecord[i_iLow]=i_atSrcRecord[i_iLow];
    108     }
    109     else//atRecord通过递归左右两边各自变为有序部分并不断增大
    110     {//最后归并左右两半部分为有序(递归中先前半部分(左边)变为有序,再后半部分(右边)变为有序)
    111         iMid=(i_iLow+i_iHigh)/2; // 将i_atSrcRecord[s..t]平分为i_atSrcRecord[s..m]和i_atSrcRecord[m+1..t]
    112         MSort(i_atSrcRecord,atRecord,i_iLow,iMid); // 递归地将i_atSrcRecord[s..m]归并为有序的atRecord[s..m]
    113         MSort(i_atSrcRecord,atRecord,iMid+1,i_iHigh); // 递归地将i_atSrcRecord[m+1..t]归并为有序的atRecord[m+1..t]
    114         Merge(atRecord,o_atDstRecord,i_iLow,iMid,i_iHigh); // 将atRecord[s..m]和atRecord[m+1..t]归并到o_atDstRecord[s..t]
    115     }
    116 }
    117 
    118 /*****************************************************************************
    119 -Fuction        : Merge
    120 -Description    : 
    121 // 将有序的i_atSrcRecord[i_iLow..i_iMid]和i_atSrcRecord[i_iMid+1..i_iHigh]归并为有序的TR[i..n]
    122 -Input            : 
    123 -Output         : 
    124 -Return         : 
    125 * Modify Date      Version         Author           Modification
    126 * -----------------------------------------------
    127 * 2017/06/15      V1.0.0         Yu Weifeng       Created
    128 ******************************************************************************/
    129 static void Merge(T_RecordType i_atSrcRecord[],T_RecordType o_atDstRecord[],int i_iLow,int i_iMid,int i_iHigh)
    130 {
    131     int iRight;
    132     int i,j;
    133     for(iRight=i_iMid+1,i=i_iLow;i_iLow<=i_iMid&&iRight<=i_iHigh;++i) // 将SR中记录由小到大地并入TR
    134     {
    135         if (i_atSrcRecord[i_iLow].Key<i_atSrcRecord[iRight].Key)//两边取小的部分保存到o_atDstRecord
    136         {
    137             o_atDstRecord[i]=i_atSrcRecord[i_iLow++];//左边更小保存起来,同时左边的指针i_iLow后移进行再次比较
    138         }
    139         else
    140         {
    141             o_atDstRecord[i]=i_atSrcRecord[iRight++];;//右边更小保存起来,同时右边的指针i后移进行再次比较
    142         }
    143     }
    144     
    145     if(i_iLow<=i_iMid)//左边还有剩的,即剩的部分都比右边的大
    146     {
    147         for(j=0;j<=i_iMid-i_iLow;j++)
    148         {
    149             o_atDstRecord[i+j]=i_atSrcRecord[i_iLow+j]; // 将剩余的i_atSrcRecord[i_iLow..i_iMid]复制到o_atDstRecord
    150         }
    151     }
    152     if(iRight<=i_iHigh)//右边还有剩的,即剩的部分都比左边的大
    153     {
    154         for(j=0;j<=i_iHigh-iRight;j++)
    155         {
    156             o_atDstRecord[i+j]=i_atSrcRecord[iRight+j]; // 将剩余的i_atSrcRecord[iRight..i_iHigh]复制到o_atDstRecord
    157         }
    158     }
    159 }
    160 
    161 /*****************************************************************************
    162 -Fuction        : TraverseRecordSeqList
    163 -Description    : TraverseRecordSeqList
    164 -Input            : 
    165 -Output         : 
    166 -Return         : 
    167 * Modify Date      Version         Author           Modification
    168 * -----------------------------------------------
    169 * 2017/06/15      V1.0.0         Yu Weifeng       Created
    170 ******************************************************************************/
    171 static void TraverseRecordSeqList(T_RecordSeqList *i_ptRecordSeqList)
    172 {
    173     int i;
    174     for(i=1;i<=i_ptRecordSeqList->iLength;i++)
    175     {
    176         printf("(%d,%d)",i_ptRecordSeqList->atRecord[i].Key,i_ptRecordSeqList->atRecord[i].OtherInfo);
    177     }
    178     printf("
    ");
    179 }
    MergeSort.c

    5)基数排序

    详细源码可访问:https://github.com/fengweiyu/DataStructAndAlgorithm
    或git clone https://github.com/fengweiyu/DataStructAndAlgorithm.git

  • 相关阅读:
    CSS动画DAY01
    第5章到8章小结
    实验9 根据材料编程
    实验5 编写、调试具有多个段的程序
    实验4 [bx]和loop的使用
    实验3 编程、编译、连接、跟踪
    第3章 寄存器(内存访问)小结
    实验2 用机器指令和汇编指令编程
    实验1 查看CPU和内存,用机器指令和汇编指令编程
    字符串生成及加密
  • 原文地址:https://www.cnblogs.com/yuweifeng/p/7284950.html
Copyright © 2011-2022 走看看