目录
一、线性表中顺序表的实现:
#include <stdio.h>
//顺序表的实现
#define MAXSIZE 50 //这里不加引号
typedef int ElemType; //使得顺序表存储其他类型元素时候可以迅速修改类型
typedef struct {
ElemType data[MAXSIZE];
int len;
} SequenceTable;
//遍历
void print_list(SequenceTable &list){
for (int i = 0; i < list.len; ++i) {
printf("The changed value is:%d\n",list.data[i]);
}
}
//顺序表中插入元素---这里list要(c++语法)引用
bool addData(SequenceTable &list,int position,ElemType data){
//判断插入的位置是否合法---首尾判断 不能插入到 len+1以外的地方 不能插入到比1小的位置上
if(position>list.len+1||position<1){
printf("The location inserted into the table is illegal");
return false;
}
//判断表中是否还有空间
if(list.len>=MAXSIZE){
printf("Insert failure space is full");
return false;
}
//把要插入的空间腾出来 后面的元素往后移动一位
for (int i = list.len-1; i >=position-1 ; i--) {
list.data[i+1]=list.data[i];
}
//插入元素
list.data[position-1]=data;
//顺序表存储的元素长度+1
list.len++;
//遍历输出
print_list(list);
return true;
}
//删除元素
bool delData(SequenceTable &list,int position){
//判断删除的位置是否合法
if(position>list.len||position<=0){
//删除的位置不合法
printf("The deleted location is invalid!");
return false;
}
//删除该位置的元素--依次往前覆盖掉要删除的那个位置的元素
for (int i = position; i < list.len; ++i) {
list.data[i-1]=list.data[i];
}
//删除成功--改变线性表长度
list.len--;
//遍历
print_list(list);
return true;
}
//修改元素
bool updateData(SequenceTable &list,int position,ElemType value){
//判断修改的位置是否合法
if(position>list.len||position<=0){
//删除的位置不合法
printf("The deleted location is invalid!");
return false;
}
//修改元素
list.data[position-1]=value;
//遍历
print_list(list);
return true;
}
int main() {
SequenceTable list;
list.data[0]=0;
list.data[1]=1;
list.data[2]=2;
list.data[3]=3;
list.len=4;
for (int i = 0; i < list.len; ++i) {
printf("Change the previous value to:%d\n",list.data[i]);
}
//插入
// addData(list,2,9);
//删除
// delData(list,1);
//修改
updateData(list,1,8);
return 0;
}
二、线性表的链式存储(链表-带头节点)
#include <stdio.h>
#include <stdlib.h>
//链表实现
typedef int ElementType;//存储的数据域类型
//linkList是指针别名 LNode* 就等价于 linkList
typedef struct LNode{
ElementType data;//数据域
struct LNode *next;//指针域
}LNode, *linkList;
//头插法构建链表--注意引用因为要改变
bool buildLinkListByHead(linkList &list){
//申请(结构体节点)空间创建头节点
list=(LNode*) malloc(sizeof(LNode));
//初始化头节点的指针域
list->next=NULL;
//循环接收输入的数据 来构建链表
ElementType x;
//不要忘记引用
scanf("%d",&x);
while (x!=9999){
//为新节点--申请节点空间
LNode *new_node=(LNode*) malloc(sizeof (LNode));
//存储数据
new_node->data=x;
//改变新节点的指针域--指向原来头节点的指针域所指向的节点地址
new_node->next=list->next;
//改变头节点的指针域--指向该元素
list->next=new_node;
//继续接收下一个数--不要忘记引用
scanf("%d",&x);
}
return true;
}
//尾插法构造链表
bool buildLinkListByTail(linkList &list){
//申请头节点空间
list=(linkList) malloc(sizeof (LNode));
//初始化头节点指针域
list->next=NULL;
//接收数据x
ElementType x;
scanf("%d",&x);
//记录最后一个节点--初始化
LNode *tailNode=list;
while (x!=9999){
//为新节点申请空间
LNode *new_node=(LNode*) malloc(sizeof(LNode));
//存储数据
new_node->data=x;
//改变新节点的指针域
new_node->next=tailNode->next;
//改变头节点的指针域
tailNode->next=new_node;
//插入完成 得到尾部节点
tailNode=new_node;
//继续接收数据
scanf("%d",&x);
}
return true;
}
//统计链表的长度
int getLength(linkList list){
int length=0;
list=list->next;
while (list){
length++;
list=list->next;
}
return length;
}
//按位置查找--本应该返回的是这个位置的节点地址
ElementType getValueByPosition(linkList list,int position){
int value;
int length= getLength(list);
//判断位置是否合法
if (position>length||position<=0){
printf("The location entered is invalid!");
return -1;
}
//遍历查找
for (int i = 0; i < position; ++i) {
//依次后移到该位置
list=list->next;
}
if (list->data== NULL){
return -1;
}
value=list->data;
return value;
}
//按位置查找--返回的是这个位置的节点地址
linkList getLNodeByPosition(linkList list,int position){
int length= getLength(list);
//判断位置是否合法
if (position>length||position<=0){
printf("The location entered is invalid!");
return NULL;
}
//遍历查找
for (int i = 0; i < position; ++i) {
//依次后移到该位置
list=list->next;
}
return list;
}
//按值查找
int getPositionByValue(linkList list,int value){
//得到第一个元素
list=list->next;
//记录位置
int position=0;
while (list&&list->data==value){
//记录位置
position++;
//依次往后移动
list=list->next;
}
return position;
}
//找到要插入节点的前一个节点
linkList getBeforeNode(linkList list,int position){
LNode *before_node=list;
//当前位置
int current=0;
for (int i = 0; i < position-1; ++i) {
before_node=before_node->next;
}
return before_node;
}
//往第i个位置插入元素--要改变链表中 某些节点的指针域了 要用 引用
bool listFrontInsert(linkList &list,int position,ElementType e){
//得到当前链表的长度
int length= getLength(list);
//判断插入的位置是否合法
if (position<=0||position>length+1){
printf("The insertion position is illegal!\n");
return false;
}
//为要插入的节点申请节点空间
LNode *new_node=(LNode*) malloc(sizeof(LNode));
new_node->data=e;
//得到要插入节点的前一个节点
LNode *before_node=getBeforeNode(list,position);
//改变插入节点的指针域
new_node->next=before_node->next;
//改变前一个节点的指针域
before_node->next=new_node;
return true;
}
//遍历链表--这里不需要引用因为不对链表做改变仅遍历查看
void ergodicList(linkList list){
//得到头节点所指向的元素
list=list->next;
//循环遍历
while (list!=NULL){
printf("%3d",list->data);
//往后移动
list=list->next;
}
//遍历完成--换行
printf("\n");
}
//链表的删除--要改变指针域 用引用
bool delLNode(linkList &list,int position){
//得到链表的长度
int length= getLength(list);
//判断要删除的位置是否合法
if (position>length||position<=0){
printf("The location to be deleted is invalid");
return false;
}
//得到要删除节点的前一个位置的节点
LNode *before_node= getBeforeNode(list,position);
//要做非空判断
if (before_node==NULL){
return false;
}
//得到要删除的节点
LNode *delNode= getLNodeByPosition(list,position);
//删除该节点
before_node->next=delNode->next;
delNode->next=NULL;
//释放空间
free(delNode);
return true;
}
int main() {
linkList list;
//头插法创建链表
// buildLinkListByHead(list);
//尾插法创建链表
buildLinkListByTail(list);
//遍历查看
ergodicList(list);
//按位置查找
// int value=getValueByPosition(list,5);
// if (value!=-1){
// //查找成功
// printf("%d\n",value);
// }
// int position= getPositionByValue(list,9);
// if (position!=0){
// //查找成功
// printf("%d\n",position);
// }
// //插入元素
// listFrontInsert(list,2,90);
//按位置查找节点
// LNode *node=getLNodeByPosition(list,2);
// printf("%d\n",node->data);
//删除节点
delLNode(list,1);
//遍历查看
ergodicList(list);
return 0;
}
三、习题练习:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;//数据域
struct node *next;//指针域
}node;
//尾插法构造链表
bool buildLinkListByTail(node* &list){
//申请头节点空间
list=(node*) malloc(sizeof (node));
//初始化头节点指针域
list->next=NULL;
//接收数据x
int x;
scanf("%d",&x);
//记录最后一个节点--初始化
node *tailNode=list;
while (x!=9999){
//为新节点申请空间
node *new_node=(node*) malloc(sizeof(node));
//存储数据
new_node->data=x;
//改变新节点的指针域
new_node->next=tailNode->next;
//改变头节点的指针域
tailNode->next=new_node;
//插入完成 得到尾部节点
tailNode=new_node;
//继续接收数据
scanf("%d",&x);
}
return true;
}
//遍历链表--这里不需要引用因为不对链表做改变仅遍历查看
void ergodicList(node* list){
//得到头节点所指向的元素
list=list->next;
//循环遍历
while (list!=NULL){
printf("%3d",list->data);
//往后移动
list=list->next;
}
//遍历完成--换行
printf("\n");
}
//查询链表的中间位置--并初始化后半部分链表L2--双指针遍历法--注意引用
void findMiddle(node* &L,node* &L2){
//L非空判断
if (L==NULL){
return;
}
//为L2创建头节点
L2=(node*) malloc(sizeof(node));
//初始化头节点
L2->next=NULL;
//双指针遍历法查找中间节点
node *before,*behind;
//初始化 这俩个指针--都指向链表L的第一个节点
before=behind=L->next;
//循环移动 before每次移动一格 behind每次移动俩格
while (behind!=NULL){
//后面节点移动一格---不要一次移动俩格--可能移动一次就为空了
behind=behind->next;
//移动一次后--注意这里要非空判断
if (behind==NULL){
//说明已经找到了中间位置--这里退出循环
break;
}
//不为空那么可以再移动一次
behind=behind->next;
//移动俩次后--要非空判断--因为只要behind为空那么 before是不可以移动的
if (behind==NULL){
//说明已经找到了中间位置--这里退出循环
break;
}
//移动before
before=before->next;
}
//移动完成后 before所在的位置即为L2的头节点所在位置
//before所在的位置的后一个节点即为L2的第一个节点所在位置
L2->next=before->next;
//断开L L2连接
before->next=NULL;
}
//原地翻转后半部分链表L2
void reverse(node* &L2){
//非空判断
if (L2==NULL){
return;
}
//准备三个指针
node *left,*middle,*right;
//左边指向第一个节点
left=L2->next;
//判断第一个节点是否为空
if (left==NULL){
return;
}
//中间指向第二个节点
middle=left->next;
//判断第二个节点是否为空
if (middle==NULL){
return;
}
//右边指向第三个节点
right=middle->next;
//在循环中进行判断
while (right!=NULL){
//翻转
//将中间节点的尾指针指向左边节点
middle->next=left;
//三个指针同时移动
left=middle;//左边节点变中间节点
middle=right;//中间节点变右边节点
right=right->next;//右边节点移动一位
}
//不要忘记右边节点为空的时候--已经退出了循环--左中节点还未完成翻转
middle->next=left;
//因为要翻转--不要忘记L2的最后一个节点指向NULL--即刚开始的第一个节点
L2->next->next=NULL;
//翻转完成--重置L2的-第一个节点
L2->next=middle;
}
//交叉合并俩个链表--三指针法
void merge(node* L,node* L2){
if (L==NULL||L2==NULL){
return;
}
node *pcur;//始终指向合成的那个链表的尾部
node *p;//指向L的第二个节点
node *q;//指向L2的第一个节点
pcur=L->next;
p=pcur->next;
q=L2->next;
while (p!=NULL){
//合并第一个q节点
pcur->next=q;
pcur=pcur->next;//后移一位pcur
q=q->next;//后移一位q
//合并第二个p节点
pcur->next=p;
pcur=pcur->next;
p=p->next;
}
//看最后那个剩在哪个上 插入即可
if (p!=NULL){
pcur->next=p;
pcur=pcur->next;
}
if (q!=NULL){
pcur->next=q;
pcur=pcur->next;
}
}
int main() {
//初始链表L
node* L;
//尾插法创建链表L
buildLinkListByTail(L);
//存储我们翻转后的链表L2
node* L2=NULL;
//初始L--遍历查看
ergodicList(L);
printf("------------\n");
//查询链表L的中间位置并初始化后半部分链表为L2
findMiddle(L,L2);
//打印L与L2
ergodicList(L);
ergodicList(L2);
printf("------------\n");
//翻转
reverse(L2);
ergodicList(L2);
printf("-------------\n");
//合并
merge(L,L2);
ergodicList(L);
return 0;
}
四、栈(stack)
#include <stdio.h>
#define MAXSIZE 50
typedef int ElementType;
typedef struct {
//栈中的元素--数组存储
ElementType data[MAXSIZE];
//始终指向栈顶的一个变量--因为是数组因此从0开始
//空栈为-1
int top;
}Stack;
//初始化栈
bool InitStack(Stack &stack){
stack.top=-1;
return true;
}
//判断栈满
bool isStackFull(Stack stack){
if (stack.top>=MAXSIZE-1){
return true;
}
return false;
}
//判断栈空
bool isStackEmpty(Stack stack){
if (stack.top==-1){
return true;
}
return false;
}
//进栈
bool push(Stack &stack,ElementType x){
//判断栈是否已满
bool isFull=isStackFull(stack);
if (isFull){
return false;
}
//进栈
stack.data[++stack.top]=x;
}
//出栈-返回出栈元素
bool pop(Stack &stack,ElementType &x){
//判断是否为空
if (isStackEmpty(stack)){
return false;
}
//出栈
x=stack.data[stack.top--];
}
int main() {
Stack stack;
InitStack(stack);
push(stack,1);
push(stack,2);
ElementType x;
pop(stack,x);
printf("%d--%d",x,stack.top);
return 0;
}
五、循环队列
1.数组形式:
#include <stdio.h>
#define MAXSIZE 3
typedef int ElementType;
typedef struct {
//数组存储--只能存储MAXSIZE-1个元素(便于判断队满)
ElementType data[MAXSIZE];
//队列尾 队列头
int rear,front;
}Queue;
//判断队满
bool isQueueFull(Queue queue){
if ((queue.rear+1)%MAXSIZE==queue.front){
return true;
}
return false;
}
//判断队空
bool isQueueEmpty(Queue queue){
if (queue.front==queue.rear){
return true;
}
return false;
}
//初始化队列
bool InitQueue(Queue &queue){
//头和尾都指向零号元素
queue.front=queue.rear=0;
return true;
}
//入队
bool push(Queue &queue,ElementType x){
//判断队满
if (isQueueFull(queue)){
return false;
}
//入队
queue.data[queue.rear]=x;
//注意这里要循环
queue.rear=(queue.rear+1)%MAXSIZE;
return true;
}
//出队
bool pop(Queue &queue,ElementType &x){
if (isQueueEmpty(queue)){
return false;
}
//出队
x=queue.data[queue.front];
//注意这里要循环
queue.front=(queue.front+1)%MAXSIZE;
return true;
}
int main() {
Queue queue;
InitQueue(queue);
push(queue,1);
push(queue,2);
push(queue,3);
ElementType x;
pop(queue,x);
printf("%d--%d",queue.rear,queue.front);
return 0;
}
2.链表形式:
#include <stdio.h>
#include <stdlib.h>
//循环队列的链式表示
typedef int ElementType;
//链表
typedef struct LinkNode{
ElementType data;
struct LinkNode *next;
}LinkNode;
//链表队列
typedef struct LinkQueue{
//链表队列头 链表队列尾
LinkNode *front,*rear;
}LinkQueue;//先进先出
//初始化链表队列
void InitLinkQueue(LinkQueue &linkQueue){
//申请节点空间
//都指向头节点
linkQueue.front=linkQueue.rear=(LinkNode *) malloc(sizeof(LinkNode));
//初始化头节点
linkQueue.front->next=NULL;
}
//判断队空
bool isEmpty(LinkQueue queue){
if (queue.front==queue.rear){
return true;
}
return false;
}
//因为是链表可以自己申请空间 所以不存在队满的情况
//入队--类似尾插法
void push(LinkQueue &queue,ElementType x){
//为新节点申请空间
LinkNode *newNode=(LinkNode*) malloc(sizeof(LinkNode));
newNode->data=x;
//连接导队列上
newNode->next=queue.rear->next;
queue.rear->next=newNode;
//rear始终指向队列尾
queue.rear=newNode;
}
//出队--front往后移动
bool pop(LinkQueue &queue,ElementType &x){
//判断队中是否为空
if (isEmpty(queue)){
return false;
}
//得到出队的该节点
LinkNode *node=queue.front->next;
//出队
x=node->data;
//不是最后一个元素-后面还有元素则--断链
queue.front->next=node->next;
//判断删除的是否是队列的最后一个节点
if (node==queue.rear){
//说明删除完后队列--队列为空了--重置rear与front
//注意重置是给rear重新指向头节点 因为后面没元素了 要重置就是重置的rear
queue.rear=queue.front;
}
free(node);
return true;
}
int main() {
LinkQueue linkQueue;
InitLinkQueue(linkQueue);
push(linkQueue,1);
ElementType x;
pop(linkQueue,x);
return 0;
}
3.习题练习
六、二叉树
1.层次建树
#include <stdio.h>
#include <stdlib.h>
//树中元素的存储类型
typedef char BiElementType;
//树的结构
typedef struct BiTNode{
//存储数据
BiElementType data;
//左孩子
struct BiTNode *lchild;
//右孩子
struct BiTNode *rchild;
}BiTNode,*BiTree;
//辅助队列
typedef struct tag{
//存储的是树中节点的地址
BiTree p;
struct tag *pnext;
}tag_t,*ptag_t;
#include "BiTree.h"
int main() {
//用来指向新申请的树节点
BiTree tnode;
//始终指向要插入节点的父亲节点
BiTree tree=NULL;
//始终指向树根
BiTree troot=NULL;
//接收数据
BiElementType c;
//队列头 队列尾 申请新的队列节点空间 pnew pcur 指向(正在插入左右孩子的)二叉树的根节点
ptag_t phead=NULL,ptail=NULL,pnew=NULL,pcur=NULL;
//循环接收键盘输入abcdefjh
while (scanf("%c",&c)){
//退出循环
if (c=='\n'){
break;
}
//创建新的树节点--创建树节点空间--calloc() 俩个参数之积 为申请的空间大小--于malloc相比它会自动初始化--初始化为0 0即为NULL
tnode=(BiTNode*) calloc(1, sizeof(BiTNode));
//初始化树节点
tnode->data=c;
//申请队列节点空间
pnew=(tag_t*) calloc(1, sizeof(tag_t));
//初始化--数据为 树中节点的地址
pnew->p=tnode;
//判断树是否为空
if (tree==NULL){
//第一次插入树--将当前节点作为树根节点
troot=tnode;
//将当前节点作为接下来要插入节点的父亲节点节点
tree=tnode;
//入队
//队列头节点赋值
phead=pnew;
//队列中的树根节点--指要进入树的父亲节点
pcur=pnew;
//队列尾节点重置
ptail=pnew;
//那么这个节点就处理完成了
continue;
}
//如果树不为空判断是否为左孩子
if (tree->lchild==NULL){
//左孩子连接树
tree->lchild=tnode;
//左孩子入队
pnew->pnext=ptail->pnext;
ptail->pnext=pnew;
//队列尾节点重置
ptail=pnew;
//那么这个节点就处理完成了
continue;
}
//如果树不为空判断是否为右孩子
if (tree->rchild==NULL){
//右孩子连接到树上
tree->rchild=tnode;
//右孩子入队
pnew->pnext=ptail->pnext;
ptail->pnext=pnew;
//注意因为是右孩子因此此时的树根节点以及满了 要改变树根了
//移动队列中的树根节点
pcur=pcur->pnext;
//将辅助队列树根节点赋值给树根节点
tree=pcur->p;
//队列尾节点重置
ptail=pnew;
//那么这个节点就处理完成了
continue;
}
}
return 0;
}
2.前中后序遍历 (就看中在哪遍历)
//前序遍历
void preOrder(BiTree tree){
if (tree==NULL){
return;
}
//中左右
printf("%c",tree->data);
//打下面的
preOrder(tree->lchild);
preOrder(tree->rchild);
}
//中序
void inOrder(BiTree tree){
if (tree==NULL){
return;
}
//左中右
inOrder(tree->lchild);
printf("%c",tree->data);
inOrder(tree->rchild);
}
//后序
void postOrder(BiTree p){
if (p==NULL){
return;
}
//左右中
postOrder(p->lchild);
postOrder(p->rchild);
printf("%c",p->data);
}
3.层序遍历--
//层序遍历
void LevelOrder(BiTree troot){
if (troot==NULL){
return;
}
//辅助队列
LinkQueue queue;
InitLinkQueue(queue);
//树根节点放入队列
push(queue,troot);
//存储出队树节点
BiTNode *deNode;
while (!isEmpty(queue)){
pop(queue,deNode);
putchar(deNode->data);
if(deNode->lchild){
//左孩子入队
push(queue,deNode->lchild);
}
if(deNode->rchild){
//右孩子入队
push(queue,deNode->rchild);
}
}
}
4.先序遍历求WPL带权路径之和
//先序遍历计算带权路径之和
int wpl_preOrder(BiTree tree,int deep){
//静态局部变量 它与全局变量作用类似 都只会初始化一次 但它仅在函数内有效
static int wpl=0;
if (tree!=NULL){
if (tree->lchild==NULL&& tree->rchild==NULL){
wpl+=tree->data*deep;
}
wpl_preOrder(tree->lchild,deep+1);
wpl_preOrder(tree->rchild,deep+1);
}
return wpl;
}
//先序遍历计算带权路径之和
int wpl_PreOrder(BiTree tree,int deep){
if (tree->lchild==NULL&&tree->rchild==NULL){
return tree->data*deep;
}
return wpl_PreOrder(tree->lchild,deep+1)+wpl_PreOrder(tree->rchild,deep+1);
}
七、OJ练习题
#include <stdio.h>
#include <stdlib.h>
/**
* 读取字符串abcdefghij,然后层次建树建立一颗二叉树,然后前序遍历输出abdhiejcfg,注意不要打印前序遍历几个汉字
*/
/**
* 读取字符串abcdefghij,然后层次建树建立一颗二叉树,
* 然后中序遍历输出 hdibjeafcg,后序遍历输出 hidjebfgca,层序遍历输出abcdefghij,注意不要输出汉字
*/
typedef char BiElementType;
typedef struct BiNode{
BiElementType data;
BiNode *lchild,*rchild;
}BiNode,*BiTree;
typedef BiTree QElementType;
//辅助链式循环队列
typedef struct LinkNode{
QElementType data;
struct LinkNode *next;
}LinkNode,*LinkList;
typedef struct LinkQueue{
LinkNode *front,*rear;
}LinkQueue;
//判断队列是否为空
bool isEmptyQueue(LinkQueue queue){
return queue.front==queue.rear;
}
//初始化队列
void InitQueue(LinkQueue &queue){
queue.rear=queue.front=(LinkNode*) calloc(1,sizeof (LinkNode));
}
//入队
void enQueue(LinkQueue &queue,QElementType data){
//存储新节点
LinkNode* qnew=(LinkNode*) calloc(1, sizeof(LinkNode));
qnew->data=data;
//入队
qnew->next=queue.rear->next;
queue.rear->next=qnew;
queue.rear=qnew;
}
//出队
BiTree deQueue(LinkQueue &queue){
if (isEmptyQueue(queue)){
return NULL;
}
//获取当前出队节点
LinkNode *qNode=queue.front->next;
//出队
queue.front->next=qNode->next;
if (queue.rear==qNode){
//说明删除的是最后一个节点--重置rear front
queue.rear=queue.front;
}
BiNode *tree=qNode->data;
//释放空间
free(qNode);
return tree;
}
//层次建树
BiTree buildBiTree(BiTree &tree){
//存储新的树节点
BiNode *tnew=NULL;
BiElementType data;
//创建辅助队列并初始化
LinkQueue queue;
InitQueue(queue);
//队列中--指向要插入的节点的父亲节点
LinkNode *qroot=NULL;
//树根节点
BiTree troot=NULL;
while (scanf("%c",&data)){
if (data=='\n'){
break;
}
tnew=(BiNode*) calloc(1,sizeof(BiNode));
tnew->data=data;
//判断是否是树根节点
if (tree==NULL){
tree=tnew;
enQueue(queue,tnew);
//此时队列中的第一个节点作为接下来要插入的父节点
qroot=queue.front->next;
troot=tnew;
continue;
}
//判断是否是左孩子节点
if (tree->lchild==NULL){
tree->lchild=tnew;
enQueue(queue,tnew);
continue;
}
//判断是否是右孩子节点
if (tree->rchild==NULL){
tree->rchild=tnew;
enQueue(queue,tnew);
qroot=qroot->next;
tree=qroot->data;
continue;
}
}
return troot;
}
//前序
void preOrder(BiTree tree){
if (tree==NULL){
return;
}
printf("%c",tree->data);
preOrder(tree->lchild);
preOrder(tree->rchild);
}
//中序
void inOrder(BiTree tree){
if (tree==NULL){
return;
}
inOrder(tree->lchild);
printf("%c",tree->data);
inOrder(tree->rchild);
}
//后序
void PostOrder(BiTree tree){
if (tree==NULL){
return;
}
PostOrder(tree->lchild);
PostOrder(tree->rchild);
printf("%c",tree->data);
}
//层序
void SequenceOrder(BiTree tree){
if (tree==NULL){
return;
}
LinkQueue queue;
InitQueue(queue);
enQueue(queue,tree);
while (!isEmptyQueue(queue)){
BiNode *tree=deQueue(queue);
printf("%c",tree->data);
if (tree->lchild){
enQueue(queue,tree->lchild);
}
if (tree->rchild){
enQueue(queue,tree->rchild);
}
}
}
int main() {
BiTree tree=NULL;
BiTree troot=NULL;
troot=buildBiTree(tree);
inOrder(troot);
printf("\n");
PostOrder(troot);
printf("\n");
SequenceOrder(troot);
printf("\n");
return 0;
}