数据结构与算法20170804
本文介绍数据结构与算法的知识,相信很多人在学校都学习过,同时为了贴近实际,文章直接附上编译通过可直接使用的源码。
一、数据结构
1.线性表:
1)带头结点的链表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
2)带头结点表意更清晰的链表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
3)不带头结点表意更清晰的链表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
4)双向链表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
5)顺序表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
2.队列:
1)链式队列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
2)顺序队列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
3.栈
1)顺序栈
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
2)栈的应用(走迷宫)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
4.二叉树与树
1)链式二叉树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
2)顺序二叉树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
3)孩子兄弟法表示的树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
5.图
1)邻接表表示的图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
2)图的遍历
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
二、算法
1.查找
1)顺序查找
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
2)折半查找
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
3)哈希表的查找
2.排序
1)插入排序
I、直接插入排序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
II、折半插入排序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
III、希尔排序
2)交换排序
I、冒泡排序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
II、快速排序
3)选择排序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
4)归并排序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
5)基数排序
详细源码可访问:https://github.com/fengweiyu/DataStructAndAlgorithm
或git clone https://github.com/fengweiyu/DataStructAndAlgorithm.git