您的位置:

用c语言将二叉树转换为双向链表,二叉树转化为二叉链表

本文目录一览:

C语言二叉树的二叉链表

#include stdio.h

#include stdlib.h

#includemalloc.h

typedef struct node

{

char data;

struct node *lchild;

struct node *rchild;

}tnode;

tnode *createtree()

{

tnode *t;

char ch;

ch=getchar();

if(ch=='0')

t=NULL;

else

{

t=(tnode *)malloc(sizeof(tnode));

t-data=ch;

t-lchild=createtree();

t-rchild=createtree();

}

return t;

}

void listtree(tnode *t)

{

if (t!=NULL)

{

printf("%c",t-data);

if(t-lchild!=NULL||t-rchild!=NULL)

{

printf("(");

listtree(t-lchild);

if(t-rchild!=NULL)

printf(",");

listtree(t-rchild);

printf(")");

}

}

}

void inorder(tnode *t)

{

if(t!=NULL)

{

inorder(t-lchild);

printf("%c\t",t-data);

inorder(t-rchild);

}

}

void leve(tnode *t)

{

tnode *quee[100];

int front,rear;

front=-1;

rear=0;

quee[rear]=t;

while(front!=rear)

{

front++;

printf("%c\t",quee[front]-data);

if(quee[front]-lchild!=NULL)

{

rear++;

quee[rear]=quee[front]-lchild;

}

if(quee[front]-rchild!=NULL)

{

rear++;

quee[rear]=quee[front]-rchild;

}

}

}

main()

{

tnode *t=NULL;

printf("请输入二叉树元素:");

t=createtree();

printf("广义表的输出:");

listtree(t);

printf("\n");

printf("二叉树的中序遍历:");

inorder(t);

printf("\n");

printf("二叉树的层次遍历:");

leve(t);

printf("\n");

system("pause");

}

/*

输入:AB00CD00E00F000

输出:A(B,C((D,E))

中序遍历: B A D C E

层次遍历:A B C D E

*/

算法 二叉树 单向链表\双向链表\循环链表

数据结构的存储

数据结构的存储一般常

用的有两种 顺序存储结构 和 链式存储结构

 2.1 顺序存储结构

发挥想象力啊。 举个列子。数组。1-2-3-4-5-6-7-8-9-10。这个就是一个顺序存储结构 ,存储是按顺序的 举 例说明啊。 栈。做开发的都熟悉。栈是先进后出 ,后进先出的形式 对不对 ?!他的你可以这样理解

hello world 在栈里面从栈底到栈顶的逻辑依次为 h-e-l-l-o-w-o-r-l-d 这就是顺序存储 再比如 队列 ,队列 是先进先出的对吧,从头到尾 h-e-l-l-o-w-o-r-l-d 就是这样排对的

 2.2 链式存储结构

再次发挥想象力 这个稍微复杂一点 这个图片我一直弄好 ,回头找美工问问,再贴上 例如 还是一个数组

1-2-3-4-5-6-7-8-9-10 链式存储就不一样了 1(地址)-2(地址)-7(地址)-4(地址)-5(地址)-9(地址)-8(地址)-3(地 址)-6(地址)-10(地址)。每个数字后面跟着一个地址 而且存储形式不再是顺序 ,也就说顺序乱了,1(地址) 1 后面跟着的这个地址指向的是 2,2 后面的地址指向的是 3,3 后面的地址指向是谁你应该清楚了吧。他 执行的时候是 1(地址)-2(地址)-3(地址)-4(地址)-5(地址)-6(地址)-7(地址)-8(地址)-9(地址)-10(地址),但是存储 的时候就是完全随机的。明白了?!

单向链表\双向链表\循环链表

还是举例子。理解最重要。不要去死记硬背 哪些什么。定义啊。逻辑啊。理解才是最重要滴

3.1 单向链表

A-B-C-D-E-F-G-H. 这就是单向链表 H 是头 A 是尾 像一个只有一个头的火车一样 只能一个头拉

着跑

3.2 双向链表

数组和链表区别:

数组:数组元素在内存上连续存放,可以通过下标查找元素;插入、删除需要移动大量元素,比较适用元

素很少变化的情况

链表:链表中的元素在内存中不是顺序存储的,查找慢,插入、删除只需要对元素指针重新赋值,效率高

3.3 循环链表

循环链表是与单向链表一样,是一种链式的存储结构,所不同的是,循环链表的最后一个结点的指针是指 向该循环链表的第一个结点或者表头结点,从而构成一个环形的链。发挥想象力 A-B-C-D-E-F-G-H-A. 绕成一个圈。就像蛇吃自己的这就是循环 不需要去死记硬背哪些理论知识。

4.1 什么是二叉树

树形结构下,两个节点以内 都称之为二叉树 不存在大于 2 的节点 分为左子树 右子树 有顺序 不能颠 倒 ,懵逼了吧,你肯定会想这是什么玩意,什么左子树右子树 ,都什么跟什么鬼? 现在我以普通话再讲 一遍,你把二叉树看成一个人 ,人的头呢就是树的根 ,左子树就是左手,右子树就是右手,左右手可以 都没有(残疾嘛,声明一下,绝非歧视残疾朋友,勿怪,勿怪就是举个例子,i am very sorry) , 左右 手呢可以有一个,就是不能颠倒。这样讲应该明白了吧

二叉树有五种表现形式

1.空的树(没有节点)可以理解为什么都没 像空气一样

2.只有根节点。 (理解一个人只有一个头 其他的什么都没,说的有点恐怖) 3.只有左子树 (一个头 一个左手 感觉越来越写不下去了)

4.只有右子树

5.左右子树都有

二叉树可以转换成森林 树也可以转换成二叉树。这里就不介绍了 你做项目绝对用不到 数据结构大致介绍这么多吧。理解为主, 别死记,死记没什么用

1、不用中间变量,用两种方法交换 A 和 B 的值

2、求最大公约数

3、模拟栈操作

 栈是一种数据结构,特点:先进后出 -

 练习:使用全局变量模拟栈的操作

//保护全局变量:在全局变量前加 static 后,这个全局变量就只能在本文件中使用 static int data[1024];//栈最多能保存 1024 个数据

static int count = 0;//目前已经放了多少个数(相当于栈顶位置)

4、排序算法

选择排序、冒泡排序、插入排序三种排序算法可以总结为如下:

都将数组分为已排序部分和未排序部分。

1.选择排序将已排序部分定义在左端,然后选择未排序部分的最小元素和未排序部分的第一个元素交换。 2.冒泡排序将已排序部分定义在右端,在遍历未排序部分的过程执行交换,将最大元素交换到最右端。 3.插入排序将已排序部分定义在左端,将未排序部分元的第一个元素插入到已排序部分合适的位置。 4.1、选择排序

 【选择排序】:最值出现在起始端

 第1趟:在n个数中找到最小(大)数与第一个数交换位置

 第2趟:在剩下n-1个数中找到最小(大)数与第二个数交换位置  重复这样的操作...依次与第三个、第四个...数交换位置

 第n-1趟,最终可实现数据的升序(降序)排列。

4.2、冒泡排序

 【冒泡排序】:相邻元素两两比较,比较完一趟,最值出现在末尾

 第1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n

个元素位置

 第2趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第n-1

个元素位置

 ............

 第n-1趟:依次比较相邻的两个数,不断交换(小数放前,大数放后)逐个推进,最值最后出现在第

2 个元素位置

5、折半查找(二分查找)

折半查找:优化查找时间(不用遍历全部数据)

折半查找的原理:

 1 数组必须是有序的

 2 必须已知 min 和 max(知道范围)

 3 动态计算 mid 的值,取出 mid 对应的值进行比较

 4 如果 mid 对应的值大于要查找的值,那么 max 要变小为 mid-1

 5 如果 mid 对应的值小于要查找的值,那么 min 要变大为 mid+1

// 已知一个有序数组, 和一个 key, 要求从数组中找到 key 对应的索引位置

字符串反正

给定字符串 "hello,world",实现将其反转。输出结果:dlrow,olleh

序数组合并

将有序数组 {1,4,6,7,9} 和 {2,3,5,6,8,9,10,11,12} 合并为 {1,2,3,4,5,6,6,7,8,9,9,10,11,12}

HASH 算法

 哈希表

例:给定值是字母 a,对应 ASCII 码值是 97,数组索引下标为 97。

这里的 ASCII 码,就算是一种哈希函数,存储和查找都通过该函数,有效地提高查找效率。

 在一个字符串中找到第一个只出现一次的字符。如输入"abaccdeff",输出'b'字符(char)是一个长度为8 的数据类型,因此总共有 256 种可能。每个字母根据其 ASCII 码值作为数组下标对应数组种的一个数 字。数组中存储的是每个字符出现的次数。

查找两个子视图的共同父视图 思路:分别记录两个子视图的所有父视图并保存到数组中,然后倒序寻找,直至找到第一个不一样的父视图。

定义一个链表

二叉树的基本操作 C语言版的

#include iostream.h

typedef struct BiTNode

{

char data;

int bit;

struct BiTNode *lchild,*rchild,*parent;

}BiTNode;

void InitBT(BiTNode *t)//1、初始化,不带头结点

{

t=NULL;

}

/*void InitBT(BiTNode *t)//初始化,带头结点

{

t=new BiTNode;

t-lchild=t-rchild=t-parent=NULL;

}*/

int EmptyBT(BiTNode *t)//判断队空

{

if(t==0)

return 1;

else

return 0;

}

BiTNode *creatBT(BiTNode *t,int b)//2、创建二叉树

{

BiTNode *p;

char ch;

cinch;

if(ch=='#')return 0;

else

{

p=new BiTNode;

p-data=ch;

p-parent=t;

p-bit=b;

t=p;

t-lchild=creatBT(t,0);

t-rchild=creatBT(t,1);

}

return t;

}

void preorder(BiTNode *t)//3、先序遍历

{

if(!EmptyBT(t))

{

coutt-data;

preorder(t-lchild);

preorder(t-rchild);

}

}

void inorder(BiTNode *t)//中序遍历

{

if(!EmptyBT(t))

{

inorder(t-lchild);

coutt-data;

inorder(t-rchild);

}

}

void postorder(BiTNode *t)//后序遍历

{

if(!EmptyBT(t))

{

postorder(t-lchild);

postorder(t-rchild);

coutt-data;

}

}

void coutBT(BiTNode *t,int m,int n,int i)//4、计算二叉树中叶子结点、度为2的结点和度为1的结点的个数

{

if(!EmptyBT(t))

{

if((t-lchild==0) (t-rchild==0))

m++;//叶子结点

else if((t-lchild!=0) (t-rchild!=0))

i++;//度为2的结点

else

n++;//度为1的结点

coutBT(t-lchild,m,n,i);

coutBT(t-rchild,m,n,i);

}

}

void coutNode(BiTNode *t,int k)//5、求二叉树中结点个数

{

if(!EmptyBT(t))

{

k++;

coutNode(t-lchild,k);

coutNode(t-rchild,k);

}

}

int BTdepth(BiTNode *t)//6、求二叉树的深度

{

int i,j;

if(EmptyBT(t))

return 0;

else

{

i=BTdepth(t-lchild);

j=BTdepth(t-rchild);

return (ij?i:j)+1;

}

}

int Xdepth(BiTNode *t,char x)//7、查找x的层数

{

int num1,num2,n;

if(t==NULL)

return 0;

else{

if(t-data==x)

return 1;

num1=Xdepth(t-lchild,x);

num2=Xdepth(t-rchild,x);

n=num1+num2;

if(num1!=0||num2!=0)

n++;

return n;

}

}

static int flag;

void SearchChild(BiTNode *t,int k)//8、查找第k个结点的左右孩子

{

if(!EmptyBT(t))

{

if(k==0)

{

cout"位置不能为0!"endl;

return;

}

else

{

flag++;

if(flag==k)

{

if(t-lchild==0)

cout"无左孩子! ";

else

cout"左孩子为:"(t-lchild-data)" ";

if(t-rchild==0)

cout"无右孩子!"endl;

else

cout"右孩子为:"(t-rchild-data)endl;

}

else

{

SearchChild(t-lchild,k);

SearchChild(t-rchild,k);

}

}

}

}

int Xancestor(BiTNode *t,char x)//9、查找x结点祖先

{

int n,num1,num2;

if(t==NULL)

return 0;

else

{

if(t-data==x)

return 1;

num1=Xancestor(t-lchild,x);

num2=Xancestor(t-rchild,x);

n=num1+num2;

if(n!=0)

{

n++;

coutt-data" "endl;

}

}

}

void BTNodePath(BiTNode *t)//10、输出所有叶子结点路径

{

if(!EmptyBT(t))

{

if((t-lchild==0) (t-rchild==0))

{

coutt-data"的路径为:";

for(BiTNode *p=t;p!=0;p=p-parent)

coutp-data;

coutendl;

}

else

{

BTNodePath(t-lchild);

BTNodePath(t-rchild);

}

}

}

void BTNodebit(BiTNode *t)//11、输出所有叶子结点编码

{

if(!EmptyBT(t))

{

if((t-lchild==0) (t-rchild==0))

{

coutt-data"的编码为:";

for(BiTNode *p=t;p-parent!=0;p=p-parent)

coutp-bit;

coutendl;

}

else

{

BTNodebit(t-lchild);

BTNodebit(t-rchild);

}

}

}

void main()

{

BiTNode *t;

int m,n,i,d,q,k;

char x;

cout"1、初始化..."endl;

InitBT(t);

cout"2、创建二叉树..."endl;

t=creatBT(t,0);

cout"3.1、先序遍历..."endl;

preorder(t);

coutendl;

cout"3.2、中序遍历..."endl;

inorder(t);

coutendl;

cout"3.3、后序遍历..."endl;

postorder(t);

coutendl;

m=n=i=0;

cout"4、计算叶子结点,度为1的结点和度为2的结点的个数..."endl;

coutBT(t,m,n,i);

cout"叶子结点个数为:"mendl;

cout"度为1的结点个数为:"nendl;

cout"度为2的结点个数为:"iendl;

q=0;

cout"5、计算结点个数..."endl;

coutNode(t,q);

cout"结点个数为:"qendl;

d=0;

cout"6、计算深度..."endl;

d=BTdepth(t);

cout"深度为:"dendl;

cout"7、求x的层数..."endl;

cout"输入x:";

cinx;

if(Xdepth(t,x)==0)

cout"x不存在!"endl;

else

coutXdepth(t,x)endl;

cout"8、输入要查找孩子的结点在先序遍历中的位置k(不等于0):";

cink;

SearchChild(t,k);

if(kflag)

cout"位置超出长度!"endl;

cout"9、查询结点的所有祖先,请输入结点x:";

cinx;

int num;

num=Xancestor(t,x);

if(num==0)

cout"结点不存在!"endl;

if(num==1)

cout"根结点无祖先!"endl;

cout"10、输出所有叶子结点路径(叶→根):"endl;

BTNodePath(t);

cout"11、输出所有叶子结点编码(叶→根):"endl;

BTNodebit(t);

}

二叉链表表示二叉树,复制一颗二叉树,如何用C语言算法设计,希望答案正确且完整

生成一个二叉树的结点

(其数据域为item,左指针域为lptr,右指针域为rptr)BiTNode *GetTreeNode(TElemType item,

BiTNode *lptr , BiTNode *rptr ){

if (!(T = (BiTNode*)malloc(sizeof(BiTNode))))

exit(1);

T- data = item;

T- lchild = lptr; T- rchild = rptr;

return T;

}

BiTNode *CopyTree(BiTNode *T) {

if (!T ) return NULL;

if (T-lchild )

newlptr = CopyTree(T-lchild);//复制左子树

else newlptr = NULL;

if (T-rchild )

newrptr = CopyTree(T-rchild);//复制右子树

else newrptr = NULL;

newT = GetTreeNode(T-data, newlptr, newrptr);

return newT;

} // CopyTree

希望对你有所帮助,因为我也是这半学期刚学的,嘿嘿

设二叉树的存储结构为二叉链表,试写出算法(C函数):将所有结点的左右子树互换

1、以二叉链表作存储结构,试编写前序、中序、后序及层次顺序遍历二叉树的算法。

#define M 10

typedef int DataType;/*元素的数据类型*/

typedef struct node

{ DataType data;

struct node *lchild,*rchild;

}BitTNode,*BiTree;

int front=0,rear=0;

BitTNode *que[10];

BitTNode *creat()

{BitTNode *t;

DataType x;

scanf("%d",x);

if(x==0) t=NULL;

else{ t=(BitTNode *)malloc(sizeof(BitTNode));

t-data=x;

t-lchild=creat();

t-rchild=creat();

}

return(t);

}/*creat*/

/* 前序遍历二叉树t */

void preorder(BiTree t)

{ if(t!=NULL)

{ printf("%4d",t-data);

preorder(t-lchild);

preorder(t-rchild);

}

}

/* 中序遍历二叉树t */

void inorder(BiTree t)

{ if(t!=NULL)

{ inorder(t-lchild);

printf("%4d",t-data);

inorder(t-rchild);

}

}

/* 后序遍历二叉树t */

void postorder(BiTree t)

{ if(t!=NULL)

{ postorder(t-lchild);

postorder(t-rchild);

printf("%4d",t-data);

}

}

void enqueue(BitTNode *t)

{if (front!=(rear+1)%M)

{ rear=(rear+1)%M;

que[rear]=t;

}

}/*enqueue*/

BitTNode * delqueue()

{ if(front==rear)return NULL;

{ front=(front+1)%M;

return (que[front]);

}

}/*delqueue*/

/* 按层次遍历二叉树t */

void levorder(BiTree t)

{ BitTNode *p;

if(t!=NULL)

{ enqueue(t);

while (front!=rear)

{ p=delqueue();

printf("%4d",p-data);

if(p-lchild!=NULL) enqueue(p-lchild);

if(p-rchild!=NULL) enqueue(p-rchild);

}

}

}/* levorder */

main()

{BitTNode *root;

root=creat();

printf("\n按先序遍历次序生成的二叉树");

printf("\n前序遍历二叉树");

preorder(root);

printf("\n中序遍历二叉树");

inorder(root);

printf("\n后序遍历二叉树");

postorder(root);

printf("\n层次顺序遍历二叉树");

levorder(root);

}

2、以二叉链表作存储结构,试编写计算二叉树深度、所有结点总数、叶子结点数、双孩子结点个数、单孩子结点个数的算法

#include stdio.h

#define MaxSize 100

typedef char ElemType;

typedef struct node

{

ElemType data;

struct node *left,*right;

} BTree;

BTree * createbt( )

{ BTree *q;

struct node1 *s[30];

int j,i,x;

printf("建立二叉树,输入结点对应的编号和值,编号和值之间用逗号隔开\n\n");

printf("i,x = ");

scanf("%d,%c",i,x);

while(i != 0 x != '$')

{ q = (BTree*)malloc(sizeof(BTree)); /*建立一个新结点q*/

q-data = x; q-left = NULL; q-right = NULL;

s[i] = q; /*q新结点地址存入s指针数组中*/

if(i != 1) /*i = 1,对应的结点是根结点*/

{ j = i / 2; /*求双亲结点的编号j*/

if(i % 2 == 0)

s[j]-left = q; /*q结点编号为偶数则挂在双亲结点j的左边*/

else

s[j]-right = q; /*q结点编号为奇数则挂在双亲结点j的右边*/

}

printf("i,x = ");

scanf("%d,%c",i,x);

}

return s[1]; /*返回根结点地址*/

}

void preorder(BTree *BT)

/* 前序遍历二叉树t */

{ if(BT!=NULL)

{ printf("%4c", BT -data);

preorder(BT -left);

preorder(BT -right);

}

}

int BTreeDepth(BTree *BT)

{

int leftdep,rightdep;

if (BT==NULL)

return(0);

else

{

leftdep=BTreeDepth(BT-left);

rightdep=BTreeDepth(BT-right);

if (leftdeprightdep)

return(leftdep+1);

else

return(rightdep+1);

}

}

int nodecount(BTree *BT)

{

if (BT==NULL)

return(0);

else

return(nodecount(BT-left)+nodecount(BT-right)+1);

}

int leafcount(BTree *BT)

{

if (BT==NULL)

return(0);

else if (BT-left==NULL BT-right==NULL)

return(1);

else

return(leafcount(BT-left)+leafcount(BT-right));

}

int notleafcount(BTree *BT)

{

if (BT==NULL)

return(0);

else if (BT-left==NULL BT-right==NULL)

return(0);

else

return(notleafcount(BT-left)+notleafcount(BT-right)+1);

}

int onesoncount(BTree *BT)

{

if (BT==NULL)

return(0);

else if ((BT-left==NULL BT-right!=NULL) ||

(BT-left!=NULL BT-right==NULL))

return(onesoncount(BT-left)+onesoncount(BT-right)+1);

else

return(onesoncount(BT-left)+onesoncount(BT-right));

}

int twosoncount(BTree *BT)

{

if (BT==NULL)

return(0);

else if (BT-left==NULL || BT-right==NULL)

return(twosoncount(BT-left)+twosoncount(BT-right));

else if (BT-left!=NULL BT-right!=NULL)

return(twosoncount(BT-left)+twosoncount(BT-right)+1);

}

main()

{

BTree *B;

B=creatree();

printf("\n按先序遍历次序生成的二叉树");

preorder(B);

printf("\n二叉树深度:%d\n",BTreeDepth(B));

printf("总结点个数:%d\n",nodecount(B));

printf("叶子结点个数:%d\n",leafcount(B));

printf("非叶子结点个数:%d\n",notleafcount(B));

printf("具有双孩子结点个数:%d\n",twosoncount(B));

printf("具有单孩子结点个数:%d\n",onesoncount(B));

}

如果还没解决你的问题,可以加我百度HI账号。

将二叉树转换为双向链表

创建一个二叉树,对这棵动态二叉树进行分析,将其用静态二叉链表表示。二叉树的动态二叉链表结构中的每个结点有三个字段:data,lchild,rchild。静态二叉链表是用数组作为存储空间,每个数组元素存储二叉树的一个结点,也有三个字段:data,lchild,rchild。lchild和rdhild分别用于存储左右孩子的下标。

用c语言将二叉树转换为双向链表,二叉树转化为二叉链表

2022-11-29
c语言单链表以及二叉树中创建时,编写函数,输入字符序列,建立

2022-11-29
层次遍历构建二叉树c语言,c语言二叉树的创建与遍历

2023-01-06
二叉树的前序遍历c语言,二叉树前序遍历c语言代码

2022-11-25
输出二叉树的层次遍历c语言,遍历二叉树C语言

2023-01-04
遍历线索化二叉树java(遍历二叉树和线索二叉树)

2022-11-15
c语言二叉树的度,c++二叉树的深度

2023-01-05
二叉树按层输出c语言,C语言二叉树怎么输入数据

2022-11-24
c语言八叉树,二叉树构造c语言实现

2022-11-26
二叉树的c语言程序求教,c语言创建二叉树代码

2023-01-06
c语言求二叉树最大深度,c语言求二叉树高度

2022-11-25
二叉树java,二叉树java实现

2023-01-10
c语言二叉排序,c语言创建排序二叉树

2022-12-02
二叉树java,二叉树java打印中根

2022-12-02
c语言层序遍历创建二叉树,二叉树的建立与遍历完整代码C语言

2022-11-23
二叉树golang,二叉树的度

2022-11-28
c语言深度优先二叉树遍历,深度优先遍历类似于二叉树的层次遍历

本文目录一览: 1、急急急!求C语言的数据结构二叉树递归遍历程序! 2、C语言二叉树的遍历。 3、C语言数据结构“遍历二叉树” 4、二叉树的创建和遍历 急急急!求C语言的数据结构二叉树递归遍历程序!

2023-12-08
java遍历二叉树,java遍历二叉树代码

2023-01-03
数据结构c语言二叉树的查找,数据结构c语言版二叉树代码

2022-11-22
java二叉树测试(二叉查找树java)

2022-11-11