二叉樹(資料結構)
介紹
- 樹(Tree)是n(n >= 0)個結點的有限集合,n = 0 時稱為空樹。在任意一棵非空樹中:
(1)有且僅有一個特定的稱為根(Root)的結點;
(2)當n > 1 時,其餘結點可分為m(m > 0)個互不相交的有限集T1,T2,……Tm,其中每個集合本身又是一棵樹,並且稱為根的子樹(SubTree); - 注意兩點:(1) 根節點是唯一的;(2) 子樹互不相交。
二叉樹
- 二叉樹是一種特殊的樹,它的特點是每個結點最多有兩個子樹(即二叉樹的度不能大於2),並且二叉樹的子樹有左右之分,其次序不能顛倒。
- 一棵深度為k 且有2^k -1 個結點的二叉樹稱為滿二叉樹。
- 如果有深度為k 的,有n 個結點的二叉樹,如果其每一個結點都與深度為k 的滿二叉樹中編號從1 至n 的結點一一對應,則稱之為完全二叉樹。
- 二叉樹性質:
性質1:在二叉樹的第i 層上最多有2^(i – 1)個結點。
性質2:深度為k 的二叉樹至多有2^i – 1 個結點。
/*************************************************************************
> File Name: tree.c
> Author: mrhjlong
> Mail: [email protected]
> Created Time: 2016年05月07日 星期六 09時57分04秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
typedef int type_t;
typedef struct node
{
type_t data;
struct node *left;
struct node * right;
}Node;
//建立結點
Node *node_create(type_t data)
{
Node *p = (Node *)malloc(sizeof(Node));
p->data = data;
p->left = NULL;
p->right = NULL;
return p;
}
//中序遍歷
void tree_in_order(Node *tree)
{
if(tree == NULL)
return;
else
{
tree_in_order(tree->left);
printf("in: %d\n", tree->data);
tree_in_order(tree->right);
}
}
//前序遍歷
void tree_pre_order(Node *tree)
{
if(tree == NULL)
return;
else
{
printf("pre: %d\n", tree->data);
tree_pre_order(tree->left);
tree_pre_order(tree->right);
}
}
//後序遍歷
void tree_post_order(Node *tree)
{
if(tree == NULL)
return;
else
{
tree_post_order(tree->left);
tree_post_order(tree->right);
printf("next: %d\n", tree->data);
}
}
void node_insert_by_recursion(Node **pTree, Node *pNode)
{
if(*pTree == NULL)
{
*pTree = pNode;
}
else if((*pTree)->data >= pNode->data)
{
node_insert_by_recursion(&((*pTree)->left), pNode);
}
else
{
node_insert_by_recursion(&((*pTree)->right), pNode);
}
}
void node_insert(Node **pTree, Node *pNode)
{
if(*pTree == NULL)
{
*pTree = pNode;
}
else
{
Node *p = *pTree;
Node *pre = p;
while(p != NULL)
{
pre = p;
if(pNode->data <= p->data)
p = p->left;
else
p = p->right;
}
if(pNode->data <= pre->data)
{
pre->left = pNode;
}
else
{
pre->right = pNode;
}
}
}
//查詢結點
Node *tree_search_by_recursion(Node *tree, type_t data)
{
if(tree == NULL)
{
printf("%d is not found!\n", data);
return NULL;
}
else if(tree->data == data)
{
return tree;
}
else if(data <= tree->data)
{
tree_search_by_recursion(tree->left, data);
}
else
{
tree_search_by_recursion(tree->right, data);
}
}
Node *tree_search(Node *tree, type_t data)
{
Node *p = tree;
while(p != NULL)
{
if(p->data == data)
return p;
else if(data <= p->data)
p = p->left;
else
p = p->right;
}
return p;
}
//求二叉樹高度
int tree_height(Node *tree)
{
int left = 0;
int right = 0;
if(tree == NULL)
return 0;
else
{
left = 1 + tree_height(tree->left);
right = 1 + tree_height(tree->right);
return (left > right ? left : right);
}
}
//銷燬二叉樹
void tree_destroy(Node **pTree)
{
if(*pTree == NULL)
return;
else
{
tree_destroy(&((*pTree)->left));
tree_destroy(&((*pTree)->right));
free(*pTree);
*pTree = NULL;
}
}
//刪除結點
void node_delete(Node **pTree,type_t data)
{
Node *pFind = *pTree;
Node *pParent = NULL;
//查詢要刪除的結點及其父結點
while(pFind != NULL)
{
if(pFind->data == data)
break;
else if(data < pFind->data)
{
pParent = pFind;
pFind = pFind->left;
}
else
{
pParent = pFind;
pFind = pFind->right;
}
}
if(pFind == NULL)
return;
else if(pFind->left == NULL || pFind->left->right == NULL)
{
if(pParent == NULL)
{
*pTree = pFind->right;
}
else
{
if(pParent->left == pFind)
pParent->left = pFind->right;
else
pParent->right = pFind->right;
}
free(pFind);
return;
}
else
{
pParent = pFind->left;
Node *pos = pParent->right;
while(pos->right != NULL)
{
pParent = pos;
pos = pos->right;
}
pParent->right = pos->left;
pFind->data = pos->data;
free(pos);
return;
}
}
int main()
{
Node *tree = NULL;
int a[] = {45, 23, 65, 100, 29, 55, 89, 10, 3, 43, 36};
int i = 0;
Node *p = NULL;
for(i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
p = node_create(a[i]);
node_insert(&tree, p);
}
// tree_destroy(&tree);
Node *pSea = tree_search(tree, 36);
if(pSea != NULL)
{
printf("search: %d\n", pSea->data);
printf("pSea: %p\n", pSea);
printf("pNode: %p\n", p);
}
printf("height: %d\n", tree_height(tree));
node_delete(&tree, 29);
tree_in_order(tree);
printf("\n");
tree_pre_order(tree);
printf("\n");
tree_post_order(tree);
return 0;
}
相關推薦
樹及二叉樹(資料結構)
一、 什麼是樹? 1,生活中的樹 : 我們知道,對於一棵樹,無論大小, 都是由數根,樹幹,節點以及樹葉構成,那麼,在資料結構中,也存在樹這種結構,與之不同的是,它是一棵倒立的樹 ,模型如下所示: 2,資料結構中的樹: 3,樹的基本概念: 以上圖
二叉樹(資料結構)
介紹 樹(Tree)是n(n >= 0)個結點的有限集合,n = 0 時稱為空樹。在任意一棵非空樹中: (1)有且僅有一個特定的稱為根(Root)的結點; (2)當n > 1 時,其餘結點可分為m(m > 0)個互不相交的有限集T1,T
JavaScript實現排序二叉樹(資料結構)
被騰訊面試了2小時演算法掛掉的前端不是好前端誰讓前端JS那麼火呢?SO 重新學習資料結構和演算法吧!排序演算法對前端來說非常重要!排序二叉樹: 左子樹小於根節點,右子樹大於根節點,子樹也滿足這樣的條件,這樣的樹叫做排序二叉樹。所以JavaScript構建這樣一個二叉樹的過程如
構建二叉樹(資料結構,李春葆)
#include <stdio.h> #include <malloc.h> #include <stdlib.h> typedef struct node { char data; struct node* lchild; struct node* rch
資料結構實驗之二叉樹四:(先序中序)還原二叉樹 (SDUT 3343)
#include <bits/stdc++.h> using namespace std; struct node { char data; struct node *lc, *rc; }; char a[100],b[100]; int n; struct node
資料結構與演算法篇 二叉樹(Binary Tree)(二)
今天要講的是二叉查詢樹(Binary Search Tree),是一種最常用的二叉搜尋樹,支援快速查詢,刪除,插入資料。 它是如何實現的呢?,其實它依靠的它的資料結構,在樹中的任意一個節點,其左子樹的每個節點的值都小於這個節點的值,右子樹都大於這個節點的值。 接下來我們來看一下二叉樹是
資料結構與演算法篇 二叉樹(Binary Tree)(一)
好多天沒有寫過資料結構和演算法了,好了今天抽出點時間二叉樹,前面講到的都是線性表,棧,佇列等等。 今天講到的是非線性表結構--樹,首先說一下什麼是樹的概念 樹的這種資料結果挺像我們現實中的樹,這裡的每一個元素我們叫做節點,用線把相鄰的節點連線起來,然後它們就成了父子關係。 A節點是
資料結構作業11—二叉樹(函式題)
6-2 二叉樹求結點數 (15 分) 編寫函式計算二叉樹中的節點個數。二叉樹採用二叉連結串列儲存結構。 函式介面定義: int NodeCountOfBiTree ( BiTree T); 其中 T是二叉樹根節點的地址。 裁判測試程式樣例: //標頭檔案
資料結構作業11—二叉樹(判斷題)
1-1若一個結點是某二叉樹的中序遍歷序列的最後一個結點,則它必是該樹的前序遍歷序列中的最後一個結點。 (2分) T F 作者: DS課程組 單位: 浙江大學 1-2若A和B都是一棵二叉樹的葉子結點,則存在這樣的二叉樹,其前序遍歷序列為…A…B
C語言_資料結構_二叉樹(遞迴)
#include <iostream> #include <algorithm> #include <stack> #include <queue> using namespace std; typedef int Statu
JAVA資料結構--根據樹高生成完全二叉樹(java實現)
public class BTree { private int node; private BTree LChild ; private BTree RChild ; private BTree(int node){ this.node = nod
7-9 還原二叉樹(25 分)
ica data ext ble 序列 col 小寫 先後 span 給定一棵二叉樹的先序遍歷序列和中序遍歷序列,要求計算該二叉樹的高度。 輸入格式: 輸入首先給出正整數N(≤50),為樹中結點總數。下面兩行先後給出先序和中序遍歷序列,均是長度為N的不包含
7-23 還原二叉樹(25 分)
else int font 區別 printf 根節點 break ++ 輸出格式 給定一棵二叉樹的先序遍歷序列和中序遍歷序列,要求計算該二叉樹的高度。 輸入格式: 輸入首先給出正整數N(≤50),為樹中結點總數。下面兩行先後給出先序和中序遍歷序列,均是長度為N的不包含重復
【題解】 bzoj1864: [Zjoi2006]三色二叉樹 (動態規劃)
nod max cout esp build == node IT ron bzoj1864,懶得復制,戳我戳我 Solution: 其實想出來了\(dp\)方程推出來了最大值,一直沒想到推最小值 \(dp[i][1/0]\)表示\(i\)號節點的子樹中的綠色染色最大值,
LeetCode 101. 對稱二叉樹(Symmetric Tree)
nod 相等 二叉 說明 turn mil init node 遞歸 題目描述 給定一個二叉樹,檢查它是否是鏡像對稱的。 例如,二叉樹 [1,2,2,3,4,4,3] 是對稱的。 1 / 2 2 / \ / 3 4 4 3 但是下面這個 [
請問二叉樹等資料結構的物理儲存結構是怎樣的?
請問二叉樹等資料結構的物理儲存結構是怎樣的? 好吧,咱們書上說了,一般兩種儲存方式: 1. 以完全二叉樹的形式用連續空間的陣列儲存; 2. 以連結串列形式儲存,即各個資料之間儲存了相關的資料的指標地址! 如果回答就是這樣,那麼我想大家也不費那神了,直接洗洗睡吧? 咱們能不能深入點:
還原二叉樹 (C語言)
題目描述 給定一棵二叉樹的先序遍歷序列和中序遍歷序列,要求計算該二叉樹的高度。 輸入描述 輸入首先給出正整數N(≤50),為樹中結點總數。下面兩行先後給出先序和中序遍歷序列,均是長度為N的不包含重複英文字母(區別大小寫)的字串。 輸出描述 輸出為一個整數,即該二叉樹的高度
還原二叉樹(25 分)
給定一棵二叉樹的先序遍歷序列和中序遍歷序列,要求計算該二叉樹的高度。 輸入格式: 輸入首先給出正整數N(≤50),為樹中結點總數。下面兩行先後給出先序和中序遍歷序列,均是長度為N的不包含重複英文字母(區別大小寫)的字串。 輸出格式: 輸出為一個整數,即該二叉樹的高度。 輸入樣例:
二叉樹(java版)
二叉樹節點類: package com.node;public class TreeNode { public int data; public TreeNode leftChild; public TreeNode rightChild; public TreeNode(int data) {
二叉樹(Binary Tree)詳解
二叉樹本身就是遞迴定義的(wikipedia): To actually define a binary tree in general, we must allow for the possibility that only one of the children may be empty.