日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树特性及详细例子

發布時間:2023/12/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树特性及详细例子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

二叉樹的性質

一般二叉樹性質:

  • 在非空二叉樹的k層上,至多有2k個節點(k>=0)
  • 高度為k的二叉樹中,最多有2k+1-1個節點(k>=0)
  • 對于任何一棵非空的二叉樹,如果葉節點個數為n0,度數為2的節點個數為n2,則有: n0 = n2 + 1
  • 完全二叉樹性質:
    只有最下面的兩層結點度數小于2,其余各層的結點度數都等于2,并且最下面一層的結點都集中在該層最左邊得若干位置上,則此二叉樹稱為完全二叉樹。

  • 具有n個節點的完全二叉樹的高度k為[log2n]
  • 對于具有n個節點的完全二叉樹,如果按照從上(根節點)到下(葉節點)和從左到右的順序對二叉樹中的所有節點從0開始到n-1進行編號,則對于任意的下標為k的節點,有:
    • 如果k=0,則它是根節點,它沒有父節點;如果k>0,則它的父節點的下標為[(i-1)/2];
    • 如果2k+1 <= n-1,則下標為k的節點的左子結點的下標為2k+1;否則,下標為k的節點沒有左子結點.
    • 如果2k+2 <= n-1,則下標為k的節點的右子節點的下標為2k+2;否則,下標為k的節點沒有右子節點

    滿二叉樹性質:
    任何結點或者是樹葉,或有兩顆非空子樹。

    在滿二叉樹中,葉節點的個數比分支節點的個數多1

    擴充二叉樹性質:

  • 在擴充二叉樹中,外部節點的個數比內部節點的個數多1
  • 對任意擴充二叉樹,外部路徑長度E和內部路徑長度I之間滿足以下關系:E = I + 2n, 其中n是內部節點個數
  • ?

    二叉樹的實現與周游

    二叉樹的順序表示:

    二叉樹的順序表示適用于完全二叉樹,根據完全二叉樹的第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

    總結

    以上是生活随笔為你收集整理的二叉树特性及详细例子的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。