二叉树特性及详细例子
生活随笔
收集整理的這篇文章主要介紹了
二叉树特性及详细例子
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二叉樹的性質
一般二叉樹性質:
完全二叉樹性質:
只有最下面的兩層結點度數小于2,其余各層的結點度數都等于2,并且最下面一層的結點都集中在該層最左邊得若干位置上,則此二叉樹稱為完全二叉樹。
- 如果k=0,則它是根節點,它沒有父節點;如果k>0,則它的父節點的下標為[(i-1)/2];
- 如果2k+1 <= n-1,則下標為k的節點的左子結點的下標為2k+1;否則,下標為k的節點沒有左子結點.
- 如果2k+2 <= n-1,則下標為k的節點的右子節點的下標為2k+2;否則,下標為k的節點沒有右子節點
滿二叉樹性質:
任何結點或者是樹葉,或有兩顆非空子樹。
在滿二叉樹中,葉節點的個數比分支節點的個數多1
擴充二叉樹性質:
?
二叉樹的實現與周游
二叉樹的順序表示:
二叉樹的順序表示適用于完全二叉樹,根據完全二叉樹的第2性質,可以建立處節點之間的關系,對于一般的二叉樹,可以將其擴充為完全二叉樹,然后用一維數組順序存儲.
以下是程序代碼:
bintree.h
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define USED 1 4 #define NOTUSED 0 5 typedef int Type; 6 7 // 二叉樹節點結構體 8 typedef struct treenode 9 { 10 int nodeIndex; 11 // 標志是否為外部節點,如果是則為0,否則為1 12 int isIn; 13 // 0表示這個節點不在二叉樹中,1表示在樹中 14 int isUsed; 15 Type element; 16 }TreeNode; 17 18 // 二叉樹結構體 19 typedef struct bintree 20 { 21 int MAXN; 22 int n; 23 TreeNode *nodelist; 24 }*Tree; 25 26 // 創建最大節點為m的空二叉樹 27 Tree createBinTree(int m) 28 { 29 int i; 30 Tree tree = NULL; 31 TreeNode *nodelist = NULL; 32 tree = malloc(sizeof(struct bintree)); 33 if (NULL != tree) 34 { 35 nodelist = malloc(m * sizeof(TreeNode)); 36 if (NULL != nodelist) 37 { 38 tree->MAXN = m; 39 tree->n = -1; 40 for (i = 0; i < m; i++) 41 { 42 nodelist[i].isUsed = NOTUSED; 43 nodelist[i].nodeIndex = i; 44 } 45 printf("\n"); 46 tree->nodelist = nodelist; 47 } 48 } 49 return tree; 50 } 51 52 // 在二叉樹末尾加入元素 53 void inTree(Tree tree, Type x, int isIn) 54 { 55 void replaceTree(Tree, Type, int, int); 56 if (tree->n + 1 < tree->MAXN) 57 { 58 replaceTree(tree, x, tree->n + 1, isIn); 59 tree->n = tree->n + 1; 60 } 61 return; 62 } 63 64 // 替換二叉樹中指定下標的元素 65 void replaceTree(Tree tree, Type x, int index, int isIn) 66 { 67 if (tree->n == -1 || (index >= 0 && index <= tree->n + 1)) 68 { 69 tree->nodelist[index].element = x; 70 tree->nodelist[index].isIn = isIn; 71 tree->nodelist[index].isUsed = USED; 72 } 73 return; 74 } 75 76 // 得到指定下標的元素 77 Type getNode(Tree tree, int index) 78 { 79 int re; 80 if (index >= 0 && index <= tree->n) 81 re = tree->nodelist[index].element; 82 return re; 83 } 84 85 // 得到父節點的元素下標 86 int parent(Tree tree, int child) 87 { 88 if (child < 0 || child > tree->n) 89 return -1; 90 else 91 return (child - 1) / 2; 92 } 93 94 // 得到右子節點的元素下標 95 int rightChild(Tree tree, int parent) 96 { 97 if (parent < 0 || parent > tree->n) 98 return -1; 99 else 100 return 2 * parent + 2; 101 } 102 103 // 得到左子節點的元素下標 104 int leftChild(Tree tree, int parent) 105 { 106 if (parent < 0 || parent > tree->n) 107 return -1; 108 else 109 return 2 * parent + 1; 110 }?
這里用的是非遞歸的周游方法,所以要用到棧,一下是自定義的棧.
stack.h
1 #include "bintree.h" 2 typedef TreeNode DataType; 3 4 typedef struct mystack 5 { 6 //數組最大長度 7 int MAXN; 8 //指定棧頂位置 9 int index; 10 DataType *ele; 11 12 }*MyStack, Stack; 13 14 15 //創建一個空棧 16 MyStack createStack(int num) 17 { 18 MyStack stack = NULL; 19 stack = malloc(sizeof(Stack)); 20 if(stack != NULL) 21 { 22 stack->ele = malloc(sizeof(DataType) * num); 23 if(stack ->ele != NULL) 24 { 25 stack ->MAXN = num; 26 stack ->index = -1; 27 } 28 } 29 return stack; 30 } 31 32 //判斷棧是否為空 33 int isEmptyStack(MyStack stack) 34 { 35 return stack ->index == -1; 36 } 37 38 //元素入棧,如果棧已經滿則返回0,否則返回1 39 int push(MyStack stack, DataType x) 40 { 41 int index = stack ->index + 1; 42 if(index >= stack ->MAXN) 43 return 0; 44 else 45 { 46 stack ->ele[index] = x; 47 stack ->index = index; 48 return 1; 49 } 50 } 51 52 //元素出棧,如果棧已經為空返回0,否則返回1 53 int pop(MyStack stack) 54 { 55 if(isEmptyStack(stack)) 56 return 0; 57 else 58 { 59 stack ->index--; 60 return 1; 61 } 62 } 63 64 //取棧頂元素 65 DataType top(MyStack stack) 66 { 67 DataType get; 68 if(!isEmptyStack(stack)) 69 get = stack ->ele[stack ->index]; 70 return get; 71 }?
bintree.c
1 #include "stack.h" 2 3 //訪問節點信息 4 int visit(TreeNode node) 5 { 6 printf(" %d", node.element); 7 return node.nodeIndex; 8 } 9 10 //先根次序周游 11 void preOrder(Tree tree, MyStack stack) 12 { 13 int index = 0; 14 TreeNode node; 15 if(!tree->nodelist[index].isUsed) 16 return; 17 push(stack,tree->nodelist[index]); 18 while(!isEmptyStack(stack)) 19 { 20 node = top(stack); 21 pop(stack); 22 if(node.isUsed == USED) 23 { 24 index = visit(node); 25 push(stack,tree->nodelist[rightChild(tree, index)]); 26 push(stack,tree->nodelist[leftChild(tree, index)]); 27 } 28 29 } 30 } 31 32 //中根次序周游 33 void inOrder(Tree tree, MyStack stack) 34 { 35 int index = 0; 36 TreeNode node; 37 if(tree->nodelist[index].isUsed == NOTUSED) 38 return; 39 do 40 { 41 while(tree->nodelist[index].isUsed == USED) 42 { 43 push(stack,tree->nodelist[index]); 44 index = leftChild(tree, index); 45 } 46 node = top(stack); 47 pop(stack); 48 index = visit(node); 49 index = rightChild(tree,index); 50 } while(tree->nodelist[index].isUsed == USED || !isEmptyStack(stack)); 51 52 } 53 54 //后根次序周游 55 void postOrder(Tree tree, MyStack stack) 56 { 57 int index = 0, rightIndex; 58 TreeNode node; 59 if(tree->nodelist[index].isUsed == NOTUSED) 60 return; 61 while(tree->nodelist[index].isUsed == USED || !isEmptyStack(stack)) 62 { 63 while(tree->nodelist[index].isUsed == USED) 64 { 65 push(stack,tree->nodelist[index]); 66 rightIndex = rightChild(tree, index); 67 index = leftChild(tree ,index); 68 if(tree->nodelist[index].isUsed == NOTUSED) 69 index = rightIndex; 70 } 71 node = top(stack); 72 pop(stack); 73 index = visit(node); 74 //如果棧不為空,且從左子樹退回,進入到右子樹遍歷 75 if(!isEmptyStack(stack) && index == leftChild(tree,top(stack).nodeIndex)) 76 index = rightChild(tree,top(stack).nodeIndex); 77 else tree->nodelist[index].isUsed = NOTUSED; 78 } 79 80 } 81 82 int main() 83 { 84 int m = 0, isIn = 1, j, buffer = 0; 85 Tree tree = NULL; 86 MyStack stack = NULL; 87 88 printf("請輸入節點個數:"); 89 scanf("%d",&m); 90 tree = createBinTree(m); 91 stack = createStack(m); 92 printf("請輸入%d個數字:",m); 93 //將0到5六個元素依次放入二叉樹中 94 for(j = 0; j < m; j++) 95 { 96 scanf(" %d", &buffer); 97 inTree(tree, buffer, isIn); 98 } 99 100 printf("先根次序周游結果為:"); 101 preOrder(tree,stack); 102 printf("\n"); 103 104 printf("中根次序周游結果為:"); 105 inOrder(tree, stack); 106 printf("\n"); 107 108 printf("后根次序周游結果為:"); 109 postOrder(tree, stack); 110 printf("\n"); 111 112 return 1; 113 }?
按圖示二叉樹輸出:
輸出結果為:
?
二叉樹連接表示:
1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef int DataType; 4 typedef struct treenode *TreeNode; 5 typedef struct treenode *BinTree; 6 7 struct treenode 8 { 9 DataType element; 10 TreeNode llink; 11 TreeNode rlink; 12 }; 13 14 BinTree createBinTree(DataType x) 15 { 16 BinTree tree = NULL; 17 tree = malloc(sizeof(struct treenode)); 18 tree->element = x; 19 return tree; 20 } 21 22 BinTree addToLeft(BinTree t, DataType x) 23 { 24 TreeNode node = NULL; 25 node = malloc(sizeof(struct treenode)); 26 if (node != NULL) 27 node->element = x; 28 t -> llink = node; 29 return node; 30 } 31 32 BinTree addToRight(BinTree t, DataType x) 33 { 34 TreeNode node = NULL; 35 node = malloc(sizeof(struct treenode)); 36 if (node != NULL) 37 node->element = x; 38 t-> rlink = node; 39 return node; 40 } 41 42 void visitRoot(BinTree tree) 43 { 44 printf("%d ", tree->element); 45 } 46 47 BinTree leftChild(BinTree tree) 48 { 49 return tree->llink; 50 } 51 52 BinTree rightChild(BinTree tree) 53 { 54 return tree->rlink; 55 } 56 //用遞歸方法 57 //先根周游 58 void preOrder(BinTree tree) 59 { 60 if(tree == NULL) 61 return; 62 visitRoot(tree); 63 preOrder(leftChild(tree)); 64 preOrder(rightChild(tree)); 65 } 66 67 //中根周游 68 void inOrder(BinTree tree) 69 { 70 if(NULL == tree) 71 return; 72 inOrder(leftChild(tree)); 73 visitRoot(tree); 74 inOrder(rightChild(tree)); 75 } 76 77 //后根周游 78 void postOrder(BinTree tree) 79 { 80 if(NULL == tree) 81 return; 82 postOrder(leftChild(tree)); 83 postOrder(rightChild(tree)); 84 visitRoot(tree); 85 } 86 87 int main() 88 { 89 BinTree left, right; 90 BinTree tree = createBinTree(5); 91 left = addToLeft(tree, 4); 92 right = addToRight(tree, 3); 93 addToLeft(left, 8); 94 addToRight(left, 7); 95 addToLeft(right, 6); 96 97 printf("先根周游次序:"); 98 preOrder(tree); 99 printf("\n"); 100 printf("中根周游次序:"); 101 inOrder(tree); 102 printf("\n"); 103 printf("后根周游算法:"); 104 postOrder(tree); 105 printf("\n"); 106 return 1; 107 }?
?
轉載于:https://www.cnblogs.com/hanyuan/archive/2012/05/10/bintree.html
總結
以上是生活随笔為你收集整理的二叉树特性及详细例子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 哪家银行的国际信用卡好用?盘点三家银行的
- 下一篇: 重新修复安装.netframework2