数据结构与算法20170804

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法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\r\n");
 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\r\n",j,i_dwPosition);
115     }
116     else
117     {
118         pInsertListNode=(T_LinkList *)malloc(sizeof(T_LinkList));
119         if(NULL==pInsertListNode)
120         {
121             printf("pInsertListNodeMallocErr\r\n");
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\r\n",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\r\n");
189     }
190     else
191     {
192         while(NULL!=ptLinkListNode->pNext)
193         {
194             ptLinkListNode=ptLinkListNode->pNext;
195             printf("%d ",ptLinkListNode->cData);
196         }
197         printf("\r\n");
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\r\n");
 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\r\n");
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\r\n",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\r\n");
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\r\n",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\r\n");
230     }
231     else
232     {
233         while(NULL!=ptLinkListNode->ptNext)
234         {
235             ptLinkListNode=ptLinkListNode->ptNext;
236             printf("%d ",ptLinkListNode->tData.cData);
237         }
238         printf("\r\n");
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\r\n");
 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\r\n",iLen,i_dwPosition);
131     }
132     else
133     {
134         ptInsertListNode=(T_LinkList *)malloc(sizeof(T_LinkList));
135         if(NULL==ptInsertListNode)
136         {
137             printf("pInsertListNodeMallocErr\r\n");
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\r\n",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\r\n");
229     }
230     else
231     {
232         while(NULL!=ptLinkListNode)
233         {
234             //printf("%d ",ptLinkListNode->tData.cData);
235             ptLinkListNode=ptLinkListNode->ptNext;
236         }
237         printf("\r\n");
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!\r\n");
 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\r\n");
122         iRet=-1;
123     }
124     else
125     {
126         if(0!=GetElementPoint(i_ptDualLinkListHead,i_dwPosition-1,&ptListNode))//找插入点的前驱
127         {//或者找插入点位置也是可以的
128             printf("ListInsertGetElementPoint Err\r\n");
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\r\n");
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\r\n");
169         iRet=-1;
170     }
171     else
172     {
173         if(0!=GetElementPoint(i_ptDualLinkListHead,i_dwPosition,&ptListNode))//找删除点位置
174         {
175             printf("ListDeleteGetElementPoint Err\r\n");
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\r\n");
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("\r\n");
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\r\n");
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\r\n");
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\r\n");
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\r\n");
 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\r\n");
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("\r\n");
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\r\n",cElementData);
 46     ExitLinkQueue(&tLinkQueue,&cElementData);
 47     printf("退出队列元素:%d\r\n",cElementData);
 48     ExitLinkQueue(&tLinkQueue,&cElementData);
 49     printf("退出队列元素:%d\r\n",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\r\n");
 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\r\n");
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("\r\n");
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\r\n",tElementData.cData);
 66     ExitSeqQueue(&tSeqQueue,&tElementData);
 67     printf("退出队列元素:%d\r\n",tElementData.cData);
 68     ExitSeqQueue(&tSeqQueue,&tElementData);
 69     printf("退出队列元素:%d\r\n",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\r\n");
 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\r\n");
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\r\n");
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("\n");
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\r\n");
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("从入口到出口一条通路如下:\r\n");
 72         PrintMaze(aMaze,iRowNum,iRankNum);
 73     }
 74     else
 75     {
 76         printf("此迷宫没有通路\r\n");
 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\r\n", __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("\n");
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("请依次输入迷宫内墙每个单元的行数,列数:\r\n");
211     for(i=0;i<iWallNum;i++)
212     {
213         scanf("%d,%d",&iWallX,&iWallY);
214         i_daiMaze[iWallX][iWallY]=0;// 修改墙的值为0
215     }
216     printf("迷宫结构如下:\r\n");
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\r\n");
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\n",IsLinkBiTreeEmpty(ptLinkBiTree),GetLinkBiTreeDepth(ptLinkBiTree));
 73     cData=GetLinkBiTreeRootData(ptLinkBiTree);
 74     if(cData!=NIL)
 75     printf("二叉树的根为%c\r\n",cData);
 76     else
 77     printf("树空,无根\n");
 78     printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");
 79     CreateLinkBiTree(&ptLinkBiTree);
 80     printf("构造二叉树后,树空否?%d(0:是1:否)树的深度=%d\n",IsLinkBiTreeEmpty(ptLinkBiTree),GetLinkBiTreeDepth(ptLinkBiTree));
 81     cData=GetLinkBiTreeRootData(ptLinkBiTree);
 82     if(cData!=NIL)
 83     printf("二叉树的根为%c\r\n",cData);
 84     else
 85     printf("树空,无根\n");
 86     printf("中序递归遍历二叉树:\n");
 87     InOrderTraverseLinkBiTree(ptLinkBiTree);
 88     printf("\n后序递归遍历二叉树:\n");
 89     PostOrderTraverseLinkBiTree(ptLinkBiTree);
 90 
 91     printf("\n请输入一个结点的值: ");
 92     scanf("%*c%c",&cData);//%*c吃掉回车符
 93     ptLinkBiTreeNode=GetLinkBiTreeNodePoint(ptLinkBiTree,cData); // p为e1的指针
 94     printf("结点的值为%c\n",GetLinkBiTreeNodeData(ptLinkBiTreeNode));
 95     printf("欲改变此结点的值,请输入新值: ");
 96     scanf("%*c%c%*c",&cData); // 后一个%*c吃掉回车符,%*c不赋值任何变量,为调用CreateBiTree()做准备
 97     AssignToLinkBiTreeNode(ptLinkBiTreeNode,cData);//"*"表示该输入项读入后不赋予任何变量,即跳过该输入值
 98     printf("层序遍历二叉树:\n");
 99     LevelOrderTraverseLinkBiTree(ptLinkBiTree);
100 
101     cOtherData=GetLinkBiTreeParentData(ptLinkBiTree,cData);
102     if(cOtherData!=NIL)
103     printf("%c的双亲是%c\n",cData,cOtherData);
104     else
105     printf("%c没有双亲\n",cData);
106     cOtherData=GetLinkBiTreeLeftChildData(ptLinkBiTree,cData);
107     if(cOtherData!=NIL)
108     printf("%c的左孩子是%c\n",cData,cOtherData);
109     else
110     printf("%c没有左孩子\n",cData);
111     cOtherData=GetLinkBiTreeRightChildData(ptLinkBiTree,cData);
112     if(cOtherData!=NIL)
113     printf("%c的右孩子是%c\n",cData,cOtherData);
114     else
115     printf("%c没有右孩子\n",cData);
116     cOtherData=GetLinkBiTreeLeftSiblingData(ptLinkBiTree,cData);
117     if(cOtherData!=NIL)
118     printf("%c的左兄弟是%c\n",cData,cOtherData);
119     else
120     printf("%c没有左兄弟\n",cData);
121     cOtherData=GetLinkBiTreeRightSiblingData(ptLinkBiTree,cData);
122     if(cOtherData!=NIL)
123     printf("%c的右兄弟是%c\n",cData,cOtherData);
124     else
125     printf("%c没有右兄弟\n",cData);
126 
127     
128     InitLinkBiTree(&ptLinkBiTreeNoRightChild);
129     printf("构造一个右子树为空的二叉树c:\n");
130     printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");
131     CreateLinkBiTree(&ptLinkBiTreeNoRightChild);
132     printf("先序递归遍历二叉树c:\n");
133     PreOrderTraverseLinkBiTree(ptLinkBiTreeNoRightChild);
134     printf("\n层序遍历二叉树c:\n");
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("先序递归遍历二叉树:\n");
142     PreOrderTraverseLinkBiTree(ptLinkBiTree);
143     printf("\n中序非递归遍历二叉树:\n");
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("先序递归遍历二叉树:\n");
151     PreOrderTraverseLinkBiTree(ptLinkBiTree);
152     printf("\n中序非递归遍历二叉树(另一种方法):\n");
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\r\n");
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("\r\n");
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("\r\n");
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("\r\n");
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\r\n",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\r\n",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\r\n",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\r\n",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\r\n",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\r\n",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\r\n",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\r\n",tElement.iData,tOtherElement.iData);
 97     tOtherElement=GetLeftChildFromSeqBiTree(atSeqBiTree,&tElement);
 98     printf("结点%d的左孩子为%d\r\n",tElement.iData,tOtherElement.iData);
 99     tOtherElement=GetRightChildFromSeqBiTree(atSeqBiTree,&tElement);
100     printf("结点%d的右孩子为%d\r\n",tElement.iData,tOtherElement.iData);
101     tOtherElement=GetLeftSiblingFromSeqBiTree(atSeqBiTree,&tElement);
102     printf("结点%d的左兄弟为%d\r\n",tElement.iData,tOtherElement.iData);
103     tOtherElement=GetRightSiblingFromSeqBiTree(atSeqBiTree,&tElement);
104     printf("结点%d的右兄弟为%d\r\n",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\r\n",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\r\n",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\r\n",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("出现结点(不空)无双亲且不是根,程序退出\r\n");
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\r\n");
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\r\n");
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\r\n");
566     }
567     else
568     {
569         i=2*i+1+i_iLeftOrRight;// 待删除子树的根结点在矩阵中的序号
570         //printf("DeleteNodePos:%d\r\n",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\r\n");
633     }
634     else
635     {
636         PreTraverseSeqBiTree(i_ptSeqBiTree,0);
637         printf("\r\n");
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\r\n");
681     }
682     else
683     {
684         InTraverseSeqBiTree(i_ptSeqBiTree,0);
685         printf("\r\n");
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\r\n");
729     }
730     else
731     {
732         PostTraverseSeqBiTree(i_ptSeqBiTree,0);
733         printf("\r\n");
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("\r\n");
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("\r\n");
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\r\n",IsChildSiblingTreeEmpty(ptChildSiblingTree),
 64         GetChildSiblingTreeRootData(ptChildSiblingTree),GetChildSiblingTreeDepth(ptChildSiblingTree));
 65     CreateChildSiblingTree(&ptChildSiblingTree);
 66     printf("构造树T后,树空否? %d(1:是0:否) 树根为%c 树的深度为%d\r\n",IsChildSiblingTreeEmpty(ptChildSiblingTree),
 67         GetChildSiblingTreeRootData(ptChildSiblingTree),GetChildSiblingTreeDepth(ptChildSiblingTree));
 68     printf("先根遍历树T:\n");
 69     PreOrderTraverseChildSiblingTree(ptChildSiblingTree);
 70     
 71 
 72     printf("\n请输入待修改的结点的值,新值: ");
 73     scanf("%c,%c%*c",&cData,&cOtherData);
 74     AssignToChildSiblingTreeNode(ptChildSiblingTree,cData,cOtherData);
 75     printf("后根遍历修改后的树T:\n");
 76     PostOrderTraverseChildSiblingTree(ptChildSiblingTree);
 77     printf("\n%c的双亲是%c,长子是%c,下一个兄弟是%c\n",cOtherData,GetChildSiblingTreeParentData(ptChildSiblingTree,cOtherData),
 78         GetChildSiblingTreeLeftChildData(ptChildSiblingTree,cOtherData),GetChildSiblingTreeRightSiblingData(ptChildSiblingTree,cOtherData));
 79 
 80 
 81     printf("建立树p:\n");
 82     InitChildSiblingTree(&ptChildSiblingTreeNoRightChildTree);
 83     CreateChildSiblingTree(&ptChildSiblingTreeNoRightChildTree);
 84     printf("层序遍历树p:\n");
 85     LevelOrderTraverseChildSiblingTree(ptChildSiblingTreeNoRightChildTree);
 86 
 87     printf("\n将树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:\n");
 92     LevelOrderTraverseChildSiblingTree(ptChildSiblingTree);
 93 
 94     printf("\n删除树T中结点e的第i棵子树,请输入e,i: ");
 95     scanf("%c,%d",&cData,&i);
 96     ptChildSiblingTreeNode=GetChildSiblingTreeNodePoint(ptChildSiblingTree,cData);
 97     DeleteChildInChildSiblingTree(ptChildSiblingTree,ptChildSiblingTreeNode,i);
 98     printf("层序遍历树T:\n");
 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包含换行符并且后面还会加上‘\0‘
206                 //如果size小于等于一行的字符串的长度,那么读入size-1个字符
207                 //acData中不包含换行符并且最后一位保留用来放‘\0‘
208                 iStringLen=strlen(acData)-1;//去掉换行符
209                 //如果是gets,把输入的一行信息存入acData中,然后将换行符置换成串结尾符‘\0‘。
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("请顺序选择有向图,有向网,无向图,无向网\n");
 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个字符):\n",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("请输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):\n");
154     else //
155     printf("请输入每条弧(边)的弧尾和弧头(以空格作为间隔):\n");
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\r\n");
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\r\n");
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\r\n",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("有向图\n");
687         break;
688         case DN: 
689             printf("有向网\n");
690         break;
691         case UDG: 
692             printf("无向图\n");
693         break;
694         case UDN: 
695             printf("无向网\n");
696     }
697     printf("%d个顶点:\n",i_ptAdjacencyListGraph->iVexNum);
698     for(i=0;i<i_ptAdjacencyListGraph->iVexNum;++i)
699     printf("%s ",i_ptAdjacencyListGraph->atVertexList[i].tData.acData);
700     printf("\n%d条弧(边):\n",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("\n");
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("深度优先搜索的结果:\n");
 43     DFSTraverse(&tGraph);
 44     printf("广度优先搜索的结果:\n");
 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("\r\n");
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("\r\n");
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\r\n",tSeqTable.ptElement[i].dwNumber,tSeqTable.ptElement[i].strName);
 63     else
 64     printf("没找到\n");
 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\r\n");
 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\r\n",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个记录的关键字\n",tSeqTable.ptElement[i].key,i);
 59     else
 60     printf("没找到\n");
 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\r\n");
 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("\r\n");
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("排序前:\n");
 58     TraverseRecordSeqList(&tSeqList1);
 59     InsertSort(&tSeqList1);
 60     printf("直接插入排序后:\n");
 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("\r\n");
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("排序前:\n");
40     TraverseRecordSeqList(&tSeqList1);
41     MergeSort(&tSeqList1);
42     printf("折半插入排序后:\n");
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("排序前:\n");
 61     TraverseRecordSeqList(&tSeqList1);
 62     SelectSort(&tSeqList1);
 63     printf("简单选择排序后:\n");
 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("\r\n");
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("排序前:\n");
 63     TraverseRecordSeqList(&tSeqList1);
 64     MergeSort(&tSeqList1);
 65     printf("归并排序后:\n");
 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("\r\n");
179 }
MergeSort.c

5)基数排序

 

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


以上是关于数据结构与算法20170804的主要内容,如果未能解决你的问题,请参考以下文章

20170804上课笔记

20170804

20170804 - 今日技能封装 - A

20170804 - 今日技能封装 - Q

关于ntp时间同步理论及配置参数-20170804

js-20170804-Math对象