當前位置:首頁 » 服務存儲 » 二叉樹鏈表數組存儲
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

二叉樹鏈表數組存儲

發布時間: 2022-06-12 03:53:12

1. 採用二叉鏈表作為存儲結構,完成二叉樹的建立,前序、中序和後序遍歷的操作,求所有葉子及結點總數的操作

#include<iostream>

#include<cstdio>

#include<stdlib.h>

using namespace std;

typedef int Elemtype;

typedef struct BiTnode

{

Elemtype data;//數據域

struct BiTnode* Lchild,*Rchild; //左右子樹域;

}BiTnode,*BiTree;

int create(BiTree *T)

{

Elemtype ch;

Elemtype temp;

scanf("%d",&ch);

temp=getchar();

if(ch==-1)

{

*T=NULL;

}

else

{

*T=(BiTree)malloc(sizeof(BiTnode) );

if(!(*T))

{

exit(-1);

}

else

{

(*T)->data=ch;

printf("請輸入%d的左節點的值",ch);

create(&(*T)->Lchild);

printf("請輸入%d的右節點的值",ch);

create(&(*T)->Rchild);

}

}

return 1;

}

void Traverse(BiTree T)//前序遍歷二叉樹

{

if(NULL==T)

{

return;

}

else

{

printf("%d ",T->data);

Traverse(T->Lchild);

Traverse(T->Rchild);

}

}

//中序遍歷二叉樹

void midTraverse(BiTree T)

{

if(T==NULL){return;}

midTraverse(T->Lchild);

printf("%d ",T->data);

midTraverse(T->Rchild);

}

//後序遍歷二叉樹

void lasTraverse(BiTree T)

{

if(T==NULL){return;}

lasTraverse(T->Lchild);

lasTraverse(T->Rchild);

printf("%d ",T->data);

}

//求二叉樹的深度

int TreeDeep(BiTree T)

{

int deep=0;

if(T)

{

int leftdeep=TreeDeep(T->Lchild);

int rightdeep=TreeDeep(T->Rchild);

deep=leftdeep>=rightdeep?leftdeep+1:rightdeep+1;

}

return deep;

}

//求二叉樹葉子節點個數

int Leafcount(BiTree T,int &num)

{

if(T)

{

if(T->Lchild==NULL&&T->Rchild==NULL)

{

num++;

}

Leafcount(T->Lchild,num);

Leafcount(T->Rchild,num);

}

return num;

}

int main()

{

BiTree T;

BiTree *p=(BiTree*)malloc(sizeof(BiTree));

int deepth=0,num=0;

printf("請輸入第一個節點的值,-1代表沒有葉節點: ");

create(&T);

printf("先序遍歷二叉樹: ");

Traverse(T);

printf(" ");

printf("中序遍歷二叉樹: ");

midTraverse(T);

printf(" ");

printf("後序遍歷二叉樹: ");

lasTraverse(T);

printf(" ");

deepth=TreeDeep(T);

printf("樹的深度:%d ",deepth);

printf(" ");

Leafcount(T,num);

printf("二叉樹的葉子節點個數為:%d ",num);

printf(" ");

return 0;

(1)二叉樹鏈表數組存儲擴展閱讀:

二叉鏈表是樹的二叉鏈表實現方式。

樹的二叉鏈表實現方式:(孩子兄弟表示法)

以二叉鏈表作為樹的存儲結構。鏈表中結點的兩個鏈域分別指向該結點的第一個孩子結點和下一個兄弟結點。

結構描述:

typedefstruct CSNode{

ElemType data;

struct CSNode *firstchild , *netsibling;

} CSNode,* CSTree;

由於二叉樹的存儲結構比較簡單,處理起來也比較方便,所以有時需要把復雜的樹,轉換為簡單的二叉樹後再作處理。

2. 一個二叉樹按順序方式存儲在一個一維數組中,如圖:

二叉樹按照層序遍歷,依次編號,按照編號的順序,存儲在連續存儲單元的方式就是二叉樹的順序存儲。


3. 二叉樹只能採用二又鏈表來存儲.,這個是否正確,為什麼

不是的.
二叉鏈表只是最直觀的一種存儲方式.而事實上,大部分的情況都不會使用二叉鏈表.除了一些動態調整樹的演算法比如平衡樹.
更為普遍的存儲方式是用線性表來儲存二叉樹.這種方式下,線性表N存儲的節點是N div 2的兒子節點.

4. c語言 二叉樹的數組順序存儲

用數組存的話很簡單
根節點存為a1
比如說當前節點為ai
那麼左兒子存為a2*i
那麼右兒子存為a2*i+1
這樣可以保證每個點都存了並且無重復

5. 設計演算法將二叉鏈表存儲的二叉樹轉換成用數組存放的順序存儲結構

//root為當前樹的根結點
//array為存儲樹的數組
//pos表示當前root所在array中的位置
//起始調用時使用alertTheTree(root, array, 0);即可,默認array數組各元素值為非法值
//標識當前位置無結點。MAX為數組array的最大長度
void alertTheTree(TreeNode *root, int *array, int pos)
{
if (root == NULL || pos >= MAX)
return;
array[pos] = root->data;
alertTheTree(root->left, array, 2 * (pos + 1) -1);
alertTheTree(root->right, array, 2 * (pos + 1));
}

6. 二叉樹的二叉鏈表存儲結構如何實現

大概這個樣子,這個是我以前寫的二叉搜索樹:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
int data,rep;
struct node *left,*right;
} node;
node* insert(node *tree,int x);
int search(node *tree,int x);
node* del(node *tree,int x);
int main()
{
char str[20],ch;
int x;
struct node *tree = NULL;
gets(str);
while (strcmp(str,"quit"))
{
if (!strcmp(str,"insert"))
{
scanf("%d",&x);
tree = insert(tree,x);
}
else if (!strcmp(str,"delete"))
{
scanf("%d",&x);
tree = del(tree,x);
}
else if (!strcmp(str,"search"))
{
scanf("%d",&x);
if (search(tree,x))
puts("Found!");
else
puts("Not Found!");
}
else
puts("There is an error!");
ch = getchar();
gets(str);
}
return 0;
}
node* insert(node *tree,int x)
{
if (tree == NULL)
{
tree = (struct node *)malloc(sizeof(struct node *));
tree->data = x;
tree->rep = 1;
tree->left = (struct node *)malloc(sizeof(struct node *));
tree->right = (struct node *)malloc(sizeof(struct node *));
tree->left = NULL;
tree->right = NULL;
}
else if (tree->data == x)
tree->rep++;
else if (x < tree->data)
tree->left = insert(tree->left,x);
else if (x > tree->data)
tree->right = insert(tree->right,x);
return tree;
}
int search(node *tree,int x)
{
if (tree == NULL)
return 0;
else if (tree->data == x)
return 1;
else if (x < tree->data)
return search(tree->left,x);
else if (x > tree->data)
return search(tree->right,x);
}
node* del(node *tree,int x)
{
struct node *p,*q;

if (tree == NULL) {}
else if (x < tree->data)
tree->left = del(tree->left,x);
else if (x > tree->data)
tree->right = del(tree->right,x);
else if (tree->data == x)
{
if (tree->rep > 1)
tree->rep--;
else
{
if (tree->left == NULL)
return tree->right;
else if (tree->right == NULL)
return tree->left;
else
{
p = tree->left;
q = tree;
while (p->right)
{
q = p;
p = p->right;
}
tree->data = p->data;
tree->rep = p->rep;
q->right = p->left;
}
}
}
return tree;
}

7. 設計一個演算法將一棵二叉鏈表存儲的二叉樹按順序存儲到數組中

思路很簡單,根放在0位置,以後假定當前位置是i,那麼左子結點在2i+1,右子結點在2i+2。比如根的左子結點在1,右子結點在2。結點1的左子結點在3,右子結點在4。定義一種空值表示沒有子結點,比如empty。
假定一個結點由3個成員組成:value, left, right
數組假定是全局的,如果不是可以作為參數傳送。
遞歸實現比較簡單:
void btree2array(node, index)
{
if(node == NULL)
array[index] = empty;
array[index] = node->value;
btree2array(node->left, index * 2 + 1);
btree2array(node->right, index * 2 + 2);
}

開始調用的時候就一句話:
btree2array(root, 0);

8. 數組,鏈表,二叉樹,這些是為了解決什麼問題而出

數據結構,用於根據實際情況選擇最合適的結構來提高處理速度。
對於查找多插入刪除少的用數組
插入刪除多,查找少的用鏈表
二叉樹也可用於查找多的存儲,查找速度相當於二分法,插入刪除的速度沒鏈錶快。

9. 建立任意二叉樹的二叉鏈表存儲,並對其進行先序、中序、後序遍歷。

#include "stdio.h"
#include "stdlib.h"
#define STACK_INIT_SIZE 10 //棧的初始長度
#define STACKINCREMENT 5 //棧的追加長度

typedef struct bitree{
char data;
struct bitree *lchild,*rchild;
}bitree; //二叉樹結點定義

typedef struct {
bitree **base;
bitree **top;
int stacksize;
}sqstack; // 鏈棧結點定義top棧頂 base棧底 且棧元素是指向二叉樹結點的二級指針
//建立一個空棧
int initstack(sqstack *s)
{s->base=(bitree *)malloc(STACK_INIT_SIZE*sizeof(bitree)); //棧底指向開辟空間
if(!s->base) exit(1); //拋出異常
s->top=s->base; //棧頂=棧尾 表示棧空
s->stacksize=STACK_INIT_SIZE; //棧長度為開辟空間大小
return 1;
}
//進棧
int push(sqstack *s,bitree *e)
{if(s->top-s->base>=s->stacksize) //如果棧滿 追加開辟空間
{s->base=(bitree *)realloc (s->base,(s->stacksize+STACKINCREMENT)* sizeof(bitree));
if(!s->base) exit(1); //拋出異常
s->top=s->base+s->stacksize; //感覺這一句沒用
s->stacksize+=STACKINCREMENT;}
*(s->top)=e;s->top++; //進棧 棧頂後移
return 1;
}
//出棧
int pop(sqstack *s,bitree **e)
{if(s->top==s->base) return 0; //棧空 返回0
--s->top;*e=*(s->top); //棧頂前移 取出棧頂元素給e
return 1;}
//取棧頂
int gettop(sqstack *s,bitree **e) //去棧頂元素 注意top指向的是棧頂的後一個
{if(s->top==s->base) return 0; //所以 s->top-1
*e=*(s->top-1);
return 1;
}
/*------------------------非遞歸-----先序建立二叉樹----------------------------------*/
bitree *createprebitree()
{char ch;bitree *ht,*p,*q;
sqstack *s;
s=malloc(sizeof(bitree)); //加上這一句為s 初始化開辟空間
ch=getchar();
if(ch!='#'&&ch!='\n') /* 輸入二叉樹先序順序 是以完全二叉樹的先序順序
不是完全二叉樹的把沒有的結點以#表示 */
{ht=(bitree *)malloc(sizeof(bitree));
ht->data=ch;
ht->lchild=ht->rchild=NULL;
p=ht;
initstack(s);
push(s,ht); //根節點進棧
while((ch=getchar())!='\n') // 算
{if(ch!='#') {q=(bitree *)malloc(sizeof(bitree)); // 法
q->data=ch; //
if(p==*(s->top-1)) p->lchild=q; // 核
else p->rchild=q; //
push(s,q);p=q; // 心
} //
else {if(p==*(s->top-1)) p->lchild=NULL; // 的
else p->rchild=NULL; //
pop(s,&p);} // 步
//
} // 驟
return ht;
}
else return NULL;
}
/*--------------------------遞歸---------先序建立二叉樹-------------------------------*/
void CreateBiTree(bitree **T) {
//按先序次序輸入二叉樹中的結點的值(一個字元),空格字元表示空樹,
//構造二叉鏈表表示二叉樹
char ch;
scanf("%c",&ch);
if(ch=='#') *T=NULL;
else{
*T=(bitree * )malloc(sizeof(bitree));
if(!*T) exit(1);
(*T)->data=ch; //生成根結點
CreateBiTree(&(*T)->lchild); //構造左子樹
CreateBiTree(&(*T)->rchild); //構造右子樹
}
}
/*--------------------------非遞歸-------中序建立二叉樹-------------------------------*/
/*--------------------------遞歸---------中序建立二叉樹-------------------------------*/
/*--------------------------非遞歸-------後序建立二叉樹-------------------------------*/
/*--------------------------遞歸---------後序建立二叉樹-------------------------------*/

/*-----------------------非遞歸------先序輸出二叉樹------------------------------*/
void preordertraverse(bitree *h)
{sqstack m;
initstack(&m);
while(h||m.base!=m.top)
{if(h) {push(&m,h);printf("%c",h->data);h=h->lchild;}
else{pop(&m,&h);
h=h->rchild;}
}
}
/*------------------------非遞歸-----中序輸出二叉樹----------------------------*/
void inordertraverse(bitree *h)
{sqstack m;
initstack(&m);
while(h||m.base!=m.top)
{if(h) {push(&m,h);h=h->lchild;}
else {
pop(&m,&h);
printf("%c",h->data);
h=h->rchild;
}
}
}
/*---------------------非遞歸----後序遍歷二叉樹----------------------------------*/
void postordertraverse(bitree *h)
{
sqstack m;
initstack(&m);
while(h||m.base!=m.top)
{if(h) {
push(&m,h);
h=h->lchild;}
else {
bitree *r; //使用r結點表示訪問了右子樹 代替標志域
gettop(&m,&h);
if(h->rchild&&h->rchild!=r)
{h=h->rchild;
push(&m,h);
h=h->lchild;}
else{pop(&m,&h);
printf("%c",h->data);
r=h;h=NULL;}
}
}
}
//層次遍歷二叉樹 用隊列 哈哈以後做
/*-------------------------------主過程-------------------------------*/
int main()
{bitree *ht;
printf("先序非遞歸建立一個二叉樹:");
if((ht=createprebitree())!=NULL) //非遞歸建立
//CreateBiTree(&ht);
//if(ht!=NULL) //遞歸建立
{
printf("先序遍歷輸出二叉樹:");
preordertraverse(ht);
putchar('\n');
printf("中序遍歷輸出二叉樹:");
inordertraverse(ht);
putchar('\n');
printf("後序遍歷輸出二叉樹:");
postordertraverse(ht);
putchar('\n');
}
else printf("空二叉樹\n");
}
這是先序遞歸和非遞歸建立二叉樹 和 先、中、後 的遍歷輸出

10. 二叉鏈表存儲結構,實現二叉樹的遍歷

前幾天寫的,輸入二叉樹的廣義表形式,建立二叉樹的鏈式存儲。輸出的是中序。有注釋,看懂了應該其他的都能寫了吧。#include<stdio.h>
#include<stdlib.h>
int n=0; //全局變數
struct tree //二叉樹結構體
{
char data;
struct tree *lc;
struct tree *rc;
};
tree *creat(char a[]) //創建樹的二叉樹
{
tree *h;
h=(tree *)malloc(sizeof(tree));
h->lc=NULL;
h->rc=NULL;
if(a[n]!=')'&&a[n]!='('&&a[n]!=',') //當a[n]為字母存入a[]
{
h->data=a[n];
n++;
}
if(a[n]=='(') //a[n]為左括弧對h->lc遞歸操作
{
n++;
h->lc=creat(a);
}
if(a[n]==',') //a[n]為逗號對h->rc遞歸操作
{
n++;
h->rc=creat(a);
return h;
}
if(a[n]==')') //a[n]為右括弧返回h
{
n++;
return h;
}
else
return h;

}
void print(tree *h) //二叉樹中序輸出
{
if(h!=NULL)
{
print(h->lc);
printf("%c",h->data);
print(h->rc);
}

}

int high(char a[]) //判斷樹的高度
{
int i=0,max=0,p=0;
while(a[i]!=0)
{
if(a[i]=='(')
{
p++;
if(max<i)
max=p;
}
if(a[i]==')')
p--;
i++;
}
if(p!=0)
{
printf("左右括弧數不等,輸入錯誤\n"); //判斷左右括弧數是否相等
exit(1);
}
return max+1;
}
void main() //主函數
{
int i=0;
tree *h;
char a[50]={0};
gets(a);
while(a[i]!=0) //判斷各種可能出現的輸入錯誤
{

if(i==0&&(a[i]=='('||a[i]==')'||a[i]==',')) //判斷數組首元素是否為字母
{
printf("首節點錯誤\n");
exit(1);
}
if(a[i]=='(') //左括弧之前一定是字母
{
if(a[i-1]=='('||a[i-1]==')'||a[i-1]==',')
{
printf("輸入錯誤\n");
exit(1);
}
}
if(a[i]!='('&&a[i]!=')'&&a[i]!=',') //兩個字母不能在一起
{
if(a[i+1]!='('&&a[i+1]!=')'&&a[i+1]!=',')
{
printf("輸入錯誤,兩個字母不能在一起\n");
exit(1);
}
}
i++;
}
h=creat(a); //創建樹
printf("該樹的高度為:%d\n",high(a));
printf("該二叉樹的中序輸出為:");
print(h);
printf("\n");
}