1. 程式人生 > >二叉樹的非遞歸遍歷

二叉樹的非遞歸遍歷

std 是否 分配 printf 棧空間 str nco 結束 oid

全部代碼

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <assert.h>
  4 
  5 typedef struct node
  6 {
  7     int nValue;
  8     struct node *pLeft;
  9     struct node *pRight;
 10 }BiTree;
 11 
 12 typedef struct node2
 13 {
 14     BiTree *nValue;
 15     struct node2 *pNext;
16 }MyStack; 17 18 typedef struct node3 19 { 20 int nCount; 21 MyStack *pTop; 22 }Stack; 23 24 void s_Init(Stack **ppStack) 25 { 26 assert(ppStack != NULL); 27 28 *ppStack = (Stack *)malloc(sizeof(Stack)); 29 if(NULL == *ppStack) 30 { 31 printf("棧空間分配失敗!\n
"); 32 exit(-1); 33 } 34 (*ppStack)->nCount = 0; 35 (*ppStack)->pTop = NULL; 36 } 37 38 void s_Push(Stack *pStack, BiTree *nNum) 39 { 40 MyStack *pTemp = NULL; 41 42 assert(pStack != NULL); 43 44 //臨時節點開辟空間 45 pTemp = (MyStack *)malloc(sizeof(MyStack));
46 if(NULL == pTemp) 47 { 48 printf("臨時節點空間分配失敗!\n"); 49 exit(-1); 50 } 51 pTemp->nValue = nNum; 52 pTemp->pNext = NULL; 53 54 //頭添加 55 //臨時節點的下一個是頭節點 56 pTemp->pNext = pStack->pTop; 57 //新節點是新棧頂 58 pStack->pTop = pTemp; 59 60 //更新棧內元素 61 ++pStack->nCount; 62 } 63 64 BiTree *s_Pop(Stack *pStack) 65 { 66 BiTree *nNum; 67 MyStack *pDel = NULL; 68 69 assert(pStack!=NULL && pStack->pTop!=NULL); 70 71 //標記 要刪除的節點 72 pDel = pStack->pTop; 73 nNum = pStack->pTop->nValue; 74 //棧頂指針下移 75 pStack->pTop = pStack->pTop->pNext; 76 //釋放空間 77 free(pDel); 78 pDel = NULL; 79 80 //更新棧內元素 81 --pStack->nCount; 82 83 return nNum; 84 } 85 86 //遞歸創建二叉樹 87 void RecCreateBiTree(BiTree **ppRoot) 88 { 89 int nNum; 90 91 assert(ppRoot!=NULL); 92 93 //輸入節點的值 94 scanf("%d", &nNum); 95 96 //檢測是否是結束標誌 97 if(0 == nNum) 98 { 99 return; 100 } 101 102 *ppRoot = (BiTree *)malloc(sizeof(BiTree)); 103 if(NULL == *ppRoot) 104 { 105 printf("*ppRoot空間分配失敗!"); 106 exit(-1); 107 } 108 (*ppRoot)->nValue = nNum; 109 (*ppRoot)->pLeft = NULL; 110 (*ppRoot)->pRight = NULL; 111 112 //處理當前節點的左和右 113 RecCreateBiTree(&(*ppRoot)->pLeft); 114 RecCreateBiTree(&(*ppRoot)->pRight); 115 } 116 117 //非遞歸前序遍歷 118 void UnRecPrevOrderTraversal(BiTree *pRoot) 119 { 120 Stack *pStack = NULL; 121 122 assert(pRoot!=NULL); 123 124 //申請輔助棧 125 s_Init(&pStack); 126 127 while(1) 128 { 129 //打印根 處理左 130 while(pRoot!=NULL) 131 { 132 printf("%d ", pRoot->nValue); 133 s_Push(pStack, pRoot); 134 pRoot = pRoot->pLeft; 135 } 136 137 //棧頂節點彈出 處理右子樹 138 pRoot = s_Pop(pStack); 139 140 //棧空 樹遍歷結束 141 if(NULL == pRoot) 142 { 143 return; 144 } 145 146 //處理右 147 pRoot = pRoot->pRight; 148 } 149 } 150 151 //非遞歸中序遍歷 152 void UnRecMidOrderTraversal(BiTree *pRoot) 153 { 154 Stack *pStack = NULL; 155 156 assert(pRoot!=NULL); 157 158 //申請輔助棧 159 s_Init(&pStack); 160 161 while(1) 162 { 163 //處理左 164 while(pRoot) 165 { 166 s_Push(pStack, pRoot); 167 pRoot = pRoot->pLeft; 168 } 169 170 //棧頂節點彈出 171 pRoot = s_Pop(pStack); 172 173 //棧空 樹遍歷結束 174 if(NULL == pRoot) 175 { 176 return; 177 } 178 179 //打印左 180 printf("%d ", pRoot->nValue); 181 182 //處理右 183 pRoot = pRoot->pRight; 184 } 185 } 186 187 //非遞歸後序遍歷 188 void UnRecLastOrderTraversal(BiTree *pRoot) 189 { 190 Stack *pStack = NULL; 191 BiTree *pFlag = NULL; 192 193 assert(pRoot!=NULL); 194 195 //申請輔助棧 196 s_Init(&pStack); 197 198 while(1) 199 { 200 //處理左 201 while(pRoot) 202 { 203 s_Push(pStack, pRoot); 204 pRoot = pRoot->pLeft; 205 } 206 207 //空棧 結束 208 if(NULL == pStack->pTop) 209 { 210 return; 211 } 212 213 //棧頂元素的右為空 或者已經被處理過 彈出 標記 214 if(NULL==pStack->pTop->nValue->pRight || pStack->pTop->nValue->pRight==pFlag) 215 { 216 pFlag = s_Pop(pStack); 217 printf("%d ", pFlag->nValue); 218 } 219 //未被處理過 繼續處理右 220 else 221 { 222 pRoot = pStack->pTop->nValue->pRight; 223 } 224 } 225 } 226 227 int main(void) 228 { 229 BiTree *pRoot = NULL; 230 RecCreateBiTree(&pRoot); 231 UnRecPrevOrderTraversal(pRoot); 232 printf("\n"); 233 UnRecMidOrderTraversal(pRoot); 234 printf("\n"); 235 UnRecLastOrderTraversal(pRoot); 236 printf("\n"); 237 238 return 0; 239 }

二叉樹的非遞歸遍歷