前言
纸上得来终觉浅,理论看着很简单,实际操作还是遇到了不小的困难,以下所有程序都可以在vc6.0中完美运行,有问题欢迎大家沟通交流一、顺序表
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int ElemType;
#define LIST_INIT_SIZE 10 /* 线性表存储空间的初始分配量 */
#define LIST_INCREMENT 2 /* 线性表存储空间的分配增量 */
typedef struct/* 线性表的动态分配顺序存储结构 */
{
ElemType *elem; /* 存储空间基址 */
int length; /* 当前长度 */
int listsize; /* 当前分配的存储容量(以sizeof(ElemType)为单位) */
}SqList;
/* 顺序表示的线性表的基本操作,包括算法2.3,2.4,2.5*/
void InitList(SqList *L) /* 算法2.3 */
{ /* 操作结果:构造一个空的顺序线性表L */
(*L).elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!(*L).elem)
exit(OVERFLOW); /* 存储分配失败 */
(*L).length=0; /* 空表长度为0 */
(*L).listsize=LIST_INIT_SIZE; /* 初始存储容量 */
}
void DestroyList(SqList *L)
{ /* 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L */
free((*L).elem);
(*L).elem=NULL;
(*L).length=0;
(*L).listsize=0;
}
/* 请将下面函数补充完整 */
Status ListInsert(SqList *L,int i,ElemType e) /* 算法2.4 */
{ /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1 */
ElemType *newbase,*q,*p;
if(i<1 || i>L->length+1) //i值不合法
return ERROR;
if(L->length >= L->listsize)
{
newbase =(ElemType *) realloc(L->elem, (L->listsize+LIST_INCREMENT) *sizeof(ElemType));
if(!newbase)
exit(OVERFLOW);
L->elem = newbase; //新基址
L->listsize += LIST_INCREMENT; //增加存储容量
}
q = L->elem+i-1; // q为插入位置
for(p = (*L).elem+(*L).length-1;p>=q;--p) // 插入位置及之后的元素右移
*(p+1) = *p;
*q = e;
++(*L).length;
return OK;
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
}
/* 请将下面函数补充完整 */
Status ListDelete(SqList *L,int i,ElemType *e) /* 算法2.5 */
{ /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
ElemType *q,*p;
if(i<1 || i>L->length)
return ERROR;
q = L->elem+L->length-1;
p = L->elem+i-1; // p为删除位置
*e = *p; //给e初值
for(p; p<q; p++) //删除位置及之后的元素左移
*p = *(p+1);
--(*L).length;
return OK;
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
}
void ListTraverse(SqList L)
{ /* 初始条件:顺序线性表L已存在 */
ElemType *p;
int i;
p=L.elem;
for(i=1;i<=L.length;i++)
printf("%3d",*p++);
printf("\n");
}
void main()
{
SqList L;
ElemType e;
Status i;
int j;
InitList(&L);
for(j=1;j<=5;j++)
i=ListInsert(&L,1,j);
printf("依次输出L的元素:");
ListTraverse(L);
i=ListDelete(&L,3,&e); /* 删除第j个数据 */
if(i==ERROR)
printf("删除元素失败\n");
else
printf("删除元素成功,其值为:%d\n",e);
printf("删除元素后L的元素:");
ListTraverse(L);
DestroyList(&L);
}
运行截图
二、链表
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int ElemType;
/*线性表的单链表存储结构 */
struct LNode
{
ElemType data;
struct LNode *next;
};
typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
/* 带有头结点的单链表的基本操作,包括算法2.8,2.9,2.10 */
void InitList(LinkList *L)
{ /* 操作结果:构造一个空的线性表L */
*L=(LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
if(!*L) /* 存储分配失败 */
exit(OVERFLOW);
(*L)->next=NULL; /* 指针域为空 */
}
void DestroyList(LinkList *L)
{ /* 初始条件:线性表L已存在。操作结果:销毁线性表L */
LinkList q;
while(*L)
{
q=(*L)->next;
free(*L);
*L=q;
}
}
Status GetElem(LinkList L,int i,ElemType *e) /* 算法2.8 */
{ /* L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
int j=1; /* j为计数器 */
LinkList p=L->next; /* p指向第一个结点 */
while(p&&j<i) /* 顺指针向后查找,直到p指向第i个元素或p为空 */
{
p=p->next;
j++;
}
if(!p||j>i) /* 第i个元素不存在 */
return ERROR;
*e=p->data; /* 取第i个元素 */
return OK;
}
/* 请将下面函数补充完整 */
Status ListInsert(LinkList L,int i,ElemType e) /* 算法2.9。不改变L */
{ /* 在带头结点的单链线性表L中第i个位置之前插入元素e */
LinkList p,s;
int j=0;
p=L;
while(p && j<i-1)
{
p=p->next;
++j;
}
if(!p|| j>i-1)
return ERROR;
s=(LinkList)malloc(sizeof(struct LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
/* 请将下面函数补充完整 */
Status ListDelete(LinkList L,int i,ElemType *e) /* 算法2.10。不改变L */
{ /* 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值 */
LinkList p=L,q;
int j = 0;
while(p->next&&j<i-1)
{
p=p->next;
j++;
}
if(!(p->next)||j<i-1) return ERROR;
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return OK;
}
void ListTraverse(LinkList L)
{
LinkList p=L->next;
while(p)
{
printf("%3d",p->data);
p=p->next;
}
printf("\n");
}
void main()
{
LinkList L;
ElemType e;
Status i;
int j;
InitList(&L);
for(j=1;j<=5;j++)
i=ListInsert(L,1,j);
printf("在L的表头依次插入1~5后:L=");
ListTraverse(L); /* 依次对元素调用print(),输出元素的值 */
GetElem(L,4,&e);
printf("第4个元素的值为:%d\n",e);
i=ListDelete(L,4,&e); /* 删除第4个数据 */
if(i==ERROR)
printf("删除元素失败\n");
else
printf("删除元素成功,其值为:%d\n",e);
printf("依次输出L的元素:");
ListTraverse(L);
DestroyList(&L);
}
三、顺序栈
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int SElemType; /* 定义栈元素类型,此句要在c3-1.h的前面 */
/* 栈的顺序存储表示 */
#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */
#define STACK_INCREMENT 2 /* 存储空间分配增量 */
typedef struct SqStack
{
SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */
SElemType *top; /* 栈顶指针 */
int stacksize; /* 当前已分配的存储空间,以元素为单位 */
}SqStack; /* 顺序栈 */
/* 顺序栈的基本操作(9个) */
void InitStack(SqStack *S)
{ /* 构造一个空栈S */
(*S).base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!(*S).base)
exit(OVERFLOW); /* 存储分配失败 */
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
}
void DestroyStack(SqStack *S)
{ /* 销毁栈S,S不再存在 */
free((*S).base);
(*S).base=NULL;
(*S).top=NULL;
(*S).stacksize=0;
}
void ClearStack(SqStack *S)
{ /* 把S置为空栈 */
(*S).top=(*S).base;
}
Status StackEmpty(SqStack S)
{ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
if(S.top==S.base)
return TRUE;
else
return FALSE;
}
int StackLength(SqStack S)
{ /* 返回S的元素个数,即栈的长度 */
return S.top-S.base;
}
Status GetTop(SqStack S,SElemType *e)
{ /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
if(S.top>S.base)
{
*e=*(S.top-1);
return OK;
}
else
return ERROR;
}
/* 请将下面函数补充完整 */
void Push(SqStack *S,SElemType e)
{ /* 插入元素e为新的栈顶元素 */
if((*S).top-(*S).base>=(*S).stacksize)
{
(*S).base=(SElemType *)realloc((*S).base,((*S).stacksize+STACK_INCREMENT)*sizeof(SElemType));
if(!(*S).base)
exit(OVERFLOW);
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACK_INCREMENT;
}
*((*S).top)++=e;
}
/* 请将下面函数补充完整 */
Status Pop(SqStack *S,SElemType *e)
{ /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
if((*S).top == (*S).base)
return ERROR;
* e = * --(*S).top;
return OK;
}
void StackTraverse(SqStack S,void(*visit)(SElemType))
{ /* 从栈底到栈顶依次对栈中每个元素调用函数visit() */
while(S.top>S.base)
visit(*S.base++);
printf("\n");
}
void print(SElemType c)
{
printf("%d ",c);
}
void main()
{
int j;
SqStack s;
SElemType e;
InitStack(&s);
for(j=1;j<=12;j++)
Push(&s,j);
printf("栈中元素依次为:");
StackTraverse(s,print);
Pop(&s,&e);
printf("弹出的栈顶元素 e=%d\n",e);
printf("栈空否:%d(1:空 0:否)\n",StackEmpty(s));
GetTop(s,&e);
printf("栈顶元素 e=%d 栈的长度为%d\n",e,StackLength(s));
ClearStack(&s);
printf("清空栈后,栈空否:%d(1:空 0:否)\n",StackEmpty(s));
DestroyStack(&s);
printf("销毁栈后,s.top=%u s.base=%u s.stacksize=%d\n",s.top,s.base, s.stacksize);
}
四、链栈
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
typedef struct linknode
{
ElemType data;
struct linknode *next;
}*LinkStack,linknode;
void InitStack(LinkStack* s)
{
*s = (LinkStack)malloc(sizeof(linknode));
(*s)->next = NULL;
}
void DestroyStack(LinkStack* s)
{
LinkStack p,q;
for(;(*s)->next!=NULL; )
{
p = (*s)->next;
q = p->next;
free(p);
(*s)->next = q;
p = q;
}
free(*s);
}
int GetLength(LinkStack s)
{
int count = 0;
for(s = s->next;s!=NULL;s = s->next)
{
count++;
}
return count;
}
Status StackEmpty(LinkStack s)
{
if (s->next==NULL)
{
return OK;
}
else return ERROR;
}
Status Push(LinkStack* s,ElemType e)
{
linknode *p;
p = (LinkStack)malloc(sizeof(struct linknode));
if(!p)
return ERROR;
p->data = e;
p->next = (*s)->next;
(*s)->next = p;
return OK;
}
Status Pop(LinkStack *s,ElemType *e)
{
linknode *p = (*s)->next;
if((*s)->next==NULL)
return ERROR;
else
{
*e = p->data;
(*s)->next = p->next;
free(p);
return OK;
}
}
Status GetTop(LinkStack s,ElemType *e)
{
linknode *p = s->next;
if(s->next==NULL)
return ERROR;
*e=p->data;
return OK;
}
void StackTraverse(LinkStack s)
{
linknode *p;
p = s->next;
while(p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
/* LinkStack p=s->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
*/
}
void ClearStack(LinkStack s)
{
LinkStack p,q;
for(;s->next != NULL; )
{
p = s->next;
q = p->next;
free(p);
s->next = q;
p = q;
}
}
void main()
{
int j = 0;
LinkStack s;
ElemType e;
InitStack(&s);
for(j=1;j<=12;j++)
Push(&s,j);
printf("栈中元素依次为:");
StackTraverse(s);
Pop(&s,&e);
printf("\n弹出的栈顶元素 e=%d",e);
printf("\n栈空否:%d(1:空 0:否)\n",StackEmpty(s));
GetTop(s,&e);
printf("栈顶元素 e=%d ",e);
printf("栈的长度:%d\n",GetLength(s));
ClearStack(s);
printf("清空栈后,栈空否:%d(1:空 0:否)\n",StackEmpty(s));
DestroyStack(&s);
}
五、链队列
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int QElemType;
/*单链队列--队列的链式存储结构 */
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear; /* 队头、队尾指针 */
}LinkQueue;
/* 链队列的基本操作(9个) */
void InitQueue(LinkQueue *Q)
{ /* 构造一个空队列Q */
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
if(!(*Q).front)
exit(OVERFLOW);
(*Q).front->next=NULL;
}
void DestroyQueue(LinkQueue *Q)
{ /* 销毁队列Q(无论空否均可) */
while((*Q).front)
{
(*Q).rear=(*Q).front->next;
free((*Q).front);
(*Q).front=(*Q).rear;
}
}
void ClearQueue(LinkQueue *Q)
{ /* 将Q清为空队列 */
QueuePtr p,q;
(*Q).rear=(*Q).front;
p=(*Q).front->next;
(*Q).front->next=NULL;
while(p)
{
q=p;
p=p->next;
free(q);
}
}
Status QueueEmpty(LinkQueue Q)
{ /* 若Q为空队列,则返回TRUE,否则返回FALSE */
if(Q.front->next==NULL)
return TRUE;
else
return FALSE;
}
int QueueLength(LinkQueue Q)
{ /* 求队列的长度 */
int i=0;
QueuePtr p;
p=Q.front;
while(Q.rear!=p)
{
i++;
p=p->next;
}
return i;
}
Status GetHead_Q(LinkQueue Q,QElemType *e) /* 避免与bo2-6.c重名 */
{ /* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */
QueuePtr p;
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next;
*e=p->data;
return OK;
}
/* 请将下面函数补充完整 */
void EnQueue(LinkQueue *Q,QElemType e)
{ /* 插入元素e为Q的新的队尾元素 */
QNode *p;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(OVERFLOW);
p->data = e;
p->next = NULL;
(*Q).rear ->next = p;
(*Q).rear = p;
}
/* 请将下面函数补充完整 */
Status DeQueue(LinkQueue *Q,QElemType *e)
{ /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
QNode *p;
if((*Q).front ==(*Q).rear)
return ERROR;
p = (*Q).front ->next;
*e = p->data;
(*Q).front->next = p->next;
if((*Q).rear == p)
(*Q).rear = (*Q).front;
free(p);
return OK;
}
void QueueTraverse(LinkQueue Q,void(*vi)(QElemType))
{ /* 从队头到队尾依次对队列Q中每个元素调用函数vi() */
QueuePtr p;
p=Q.front->next;
while(p)
{
vi(p->data);
p=p->next;
}
printf("\n");
}
void print(QElemType i)
{
printf("%d ",i);
}
void main()
{
int i;
QElemType d;
LinkQueue q;
InitQueue(&q);
printf("成功地构造了一个空队列!\n");
printf("是否空队列?%d(1:空 0:否) ",QueueEmpty(q));
printf("队列的长度为%d\n",QueueLength(q));
EnQueue(&q,-5);
EnQueue(&q,5);
EnQueue(&q,10);
printf("插入3个元素(-5,5,10)后,队列的长度为%d\n",QueueLength(q));
printf("是否空队列?%d(1:空 0:否) ",QueueEmpty(q));
printf("队列的元素依次为:");
QueueTraverse(q,print);
i=GetHead_Q(q,&d);
if(i==OK)
printf("队头元素是:%d\n",d);
DeQueue(&q,&d);
printf("删除了队头元素%d\n",d);
i=GetHead_Q(q,&d);
if(i==OK)
printf("新的队头元素是:%d\n",d);
ClearQueue(&q);
printf("清空队列后,q.front=%u q.rear=%u q.front->next=%u\n",q.front,q.rear,q.front->next);
DestroyQueue(&q);
printf("销毁队列后,q.front=%u q.rear=%u\n",q.front, q.rear);
}
六、循环队列
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define MAXQSIZE 100
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int QElemType;
typedef struct
{
QElemType *elem;
int front;
int rear;
}LinkQueue;
/* 循环队列的基本操作(9个) */
void InitQueue(LinkQueue *Q)
{
Q -> elem = (QElemType *)malloc(sizeof(QElemType) * MAXQSIZE);
Q->front = Q->rear = 0;
}
void DestroyQueue(LinkQueue *Q)
{
if(Q->elem)
{
free(Q->elem);
}
Q->elem=0;
Q->front=Q->rear=0;
}
void ClearQueue(LinkQueue *Q)
{
Q->front=Q->rear=0;
}
Status QueueEmpty(LinkQueue *Q)
{
if(Q->rear == Q->front)
return TRUE;
else
return FALSE;
}
int QueueLength(LinkQueue *Q)
{
int length;
length = (Q->rear-Q->front+MAXQSIZE)%MAXQSIZE;
return length;
}
Status GetHead_Q(LinkQueue *Q,QElemType *e)
{
if(Q->rear==Q->front)
{
return ERROR;
}
*e=Q->elem[Q->front];
return OK;
}
void EnQueue(LinkQueue *Q,QElemType e)
{
if((Q->rear+1)%MAXQSIZE==Q->front)
{
printf("队列满");
}
Q->elem[Q->rear]=e;
Q->rear=(Q->rear+1)%MAXQSIZE;
}
Status DeQueue(LinkQueue *Q,QElemType *e)
{
if(Q->rear==Q->front)
{
return ERROR;
}
*e=Q->elem[Q->front];
Q->front=(Q->front+1)%MAXQSIZE;
return OK;
}
void QueueTraverse(LinkQueue *Q,void(*vi)(QElemType))
{
{
int i=Q->front;
while(i!=Q->rear)
{
vi(Q->elem[i]);
i=(i+1)%MAXQSIZE;
}
printf("\n");
}
}
void print(QElemType i)
{
printf("%d ",i);
}
void main()
{
int i;
QElemType d;
LinkQueue q;
InitQueue(&q);
printf("成功地构造了一个空队列!\n");
printf("是否空队列?%d(1:空 0:否) ",QueueEmpty(&q));
printf("队列的长度为%d\n",QueueLength(&q));
EnQueue(&q,-5);
EnQueue(&q,5);
EnQueue(&q,10);
printf("插入3个元素(-5,5,10)后,队列的长度为%d\n",QueueLength(&q));
printf("是否空队列?%d(1:空 0:否) ",QueueEmpty(&q));
printf("队列的元素依次为:");
QueueTraverse(&q,print);
i=GetHead_Q(&q,&d);
if(i==OK)
printf("队头元素是:%d\n",d);
DeQueue(&q,&d);
printf("删除了队头元素%d\n",d);
i=GetHead_Q(&q,&d);
if(i==OK)
printf("新的队头元素是:%d\n",d);
ClearQueue(&q);
printf("清空队列后,q.front=%u q.rear=%u ",q.front,q.rear);
DestroyQueue(&q);
printf("销毁队列后,q.front=%u q.rear=%u\n",q.front, q.rear);
}
七、二叉树的遍历
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef char TElemType;
TElemType Nil=' '; /* 字符型以空格符为空 */
/*二叉树的二叉链表存储表示 */
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
}BiTNode,*BiTree;
void InitBiTree(BiTree *T)
{ /* 操作结果:构造空二叉树T */
*T=NULL;
}
void CreateBiTree(BiTree *T)
{ /* 按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中定义),*/
/* 构造二叉链表表示的二叉树T。变量Nil表示空(子)树。有改动 */
//完成本函数
TElemType ch;
scanf("%c",&ch);
if(ch==Nil) *T=NULL;
else{
*T=(BiTree)malloc(sizeof(BiTNode));;
(*T)->data=ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
void DestroyBiTree(BiTree *T)
{ /* 初始条件:二叉树T存在。操作结果:销毁二叉树T */
if(*T) /* 非空树 */
{
if((*T)->lchild) /* 有左孩子 */
DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
if((*T)->rchild) /* 有右孩子 */
DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
free(*T); /* 释放根结点 */
*T=NULL; /* 空指针赋0 */
}
}
void PreOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数。算法6.1,有改动 */
/* 操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次 */
if(T) /* T不空 */
{
Visit(T->data); /* 先访问根结点 */
PreOrderTraverse(T->lchild,Visit); /* 再先序遍历左子树 */
PreOrderTraverse(T->rchild,Visit); /* 最后先序遍历右子树 */
}
}
void InOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数 */
/* 操作结果:中序递归遍历T,对每个结点调用函数Visit一次且仅一次 */
if(T)
{
InOrderTraverse(T->lchild,Visit); /* 先中序遍历左子树 */
Visit(T->data); /* 再访问根结点 */
InOrderTraverse(T->rchild,Visit); /* 最后中序遍历右子树 */
}
}
void PostOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数 */
/* 操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次 */
if(T) /* T不空 */
{
PostOrderTraverse(T->lchild,Visit); /* 先后序遍历左子树 */
PostOrderTraverse(T->rchild,Visit); /* 再后序遍历右子树 */
Visit(T->data); /* 最后访问根结点 */
}
}
Status BiTreeEmpty(BiTree T)
{ /* 初始条件:二叉树T存在。操作结果:若T为空二叉树,则返回TRUE,否则FALSE */
if(T)
return FALSE;
else
return TRUE;
}
TElemType Root(BiTree T)
{ //初始条件:二叉树T存在。操作结果:返回T的根
if(BiTreeEmpty(T))
return Nil;
else
return T->data;
}
void visitT(TElemType e)
{
printf("%c ",e);
}
void main()
{
BiTree T;
TElemType e1;
InitBiTree(&T);
printf("构造空二叉树后,树空否?%d(1:是 0:否)\n",BiTreeEmpty(T));
e1=Root(T);
if(e1!=Nil)
printf("二叉树的根为: %c\n",e1);
else
printf("树空,无根\n");
printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");
CreateBiTree(&T);
printf("建立二叉树后,树空否?%d(1:是 0:否) \n",BiTreeEmpty(T));
e1=Root(T);
if(e1!=Nil)
printf("二叉树的根为: %c",e1);
else
printf("树空,无根");
printf("\n先序递归遍历二叉树:");
PreOrderTraverse(T,visitT);
printf("\n中序递归遍历二叉树:");
InOrderTraverse(T,visitT);
printf("\n后序递归遍历二叉树:");
PostOrderTraverse(T,visitT);
DestroyBiTree(&T);
}
//非递归实现中序遍历
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef char TElemType;
TElemType Nil=' '; /* 字符型以空格符为空 */
/*二叉树的二叉链表存储表示 */
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
}BiTNode,*BiTree;
typedef BiTree BElemType;
typedef struct linknode
{
BElemType data;
struct linknode *next;
}*LinkStack,linknode;
void InitStack(LinkStack* s)
{
*s = (LinkStack)malloc(sizeof(linknode));
(*s)->next = NULL;
}
void DestroyStack(LinkStack* s)
{
LinkStack p,q;
for(;(*s)->next!=NULL; )
{
p = (*s)->next;
q = p->next;
free(p);
(*s)->next = q;
p = q;
}
free(*s);
}
Status StackEmpty(LinkStack s)
{
if (s->next==NULL)
{
return OK;
}
else return ERROR;
}
Status Push(LinkStack *s,BElemType e)
{
linknode *p;
p = (LinkStack)malloc(sizeof(struct linknode));
if(!p)
return ERROR;
p->data = e;
p->next = (*s)->next;
(*s)->next = p;
return OK;
}
Status Pop(LinkStack *s,BElemType *e)
{
linknode *p = (*s)->next;
if((*s)->next==NULL)
return ERROR;
else
{
*e = p->data;
(*s)->next = p->next;
free(p);
return OK;
}
}
void InitBiTree(BiTree *T)
{ /* 操作结果:构造空二叉树T */
*T=NULL;
}
void CreateBiTree(BiTree *T)
{ /* 按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中定义),*/
/* 构造二叉链表表示的二叉树T。变量Nil表示空(子)树。有改动 */
//完成本函数
TElemType ch;
scanf("%c",&ch);
if(ch==Nil) *T=NULL;
else{
*T=(BiTree)malloc(sizeof(BiTNode));;
(*T)->data=ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
void DestroyBiTree(BiTree *T)
{ /* 初始条件:二叉树T存在。操作结果:销毁二叉树T */
if(*T) /* 非空树 */
{
if((*T)->lchild) /* 有左孩子 */
DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
if((*T)->rchild) /* 有右孩子 */
DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
free(*T); /* 释放根结点 */
*T=NULL; /* 空指针赋0 */
}
}
Status BiTreeEmpty(BiTree T)
{ /* 初始条件:二叉树T存在。操作结果:若T为空二叉树,则返回TRUE,否则FALSE */
if(T)
return FALSE;
else
return TRUE;
}
TElemType Root(BiTree T)
{ //初始条件:二叉树T存在。操作结果:返回T的根
if(BiTreeEmpty(T))
return Nil;
else
return T->data;
}
Status visitT(TElemType e)
{
printf("%c",e);
return OK;
}
Status Inorder(BiTree T,Status(*Visit)(TElemType e))
{
LinkStack s;
BiTree p;
p=T;
InitStack(&s);
while(p||!StackEmpty(s))
{
if(p!=NULL)
{
Push(&s,p);
p = p->lchild;
}
else{
Pop(&s,&p);
if(!Visit(p->data))
return ERROR;
p = p->rchild;
}
}
return OK;
}
void main()
{
BiTree T;
TElemType e1;
InitBiTree(&T);
printf("构造空二叉树后,树空否?%d(1:是 0:否)\n",BiTreeEmpty(T));
e1=Root(T);
if(e1!=Nil)
printf("二叉树的根为: %c\n",e1);
else
printf("树空,无根\n");
printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");
CreateBiTree(&T);
printf("建立二叉树后,树空否?%d(1:是 0:否) \n",BiTreeEmpty(T));
e1=Root(T);
if(e1!=Nil)
printf("二叉树的根为: %c",e1);
else
printf("树空,无根");
printf("\n中序非递归遍历二叉树:");
Inorder(T,visitT);
DestroyBiTree(&T);
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210708211118652.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1Nzk2MTMz,size_16,color_FFFFFF,t_70)
八、二叉树综合操作
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<stdio.h>
#include<stdlib.h>
#include<process.h> /* exit() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef char TElemType;
TElemType Nil=' '; /* 字符型以空格符为空 */
/*二叉树的二叉链表存储表示 */
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
}BiTNode,*BiTree;
void InitBiTree(BiTree *T)
{ /* 操作结果:构造空二叉树T */
*T=NULL;
}
void CreateBiTree(BiTree *T)
{ TElemType ch;
scanf("%c",&ch);
if(ch==Nil) *T=NULL;
else{
*T=(BiTree)malloc(sizeof(BiTNode));;
(*T)->data=ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
void DestroyBiTree(BiTree *T)
{ /* 初始条件:二叉树T存在。操作结果:销毁二叉树T */
if(*T) /* 非空树 */
{
if((*T)->lchild) /* 有左孩子 */
DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
if((*T)->rchild) /* 有右孩子 */
DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
free(*T); /* 释放根结点 */
*T=NULL; /* 空指针赋0 */
}
}
int getMaxDepth(BiTree T) {
if (T == NULL)
return 0;
else {
int left = getMaxDepth(T->lchild);
int right = getMaxDepth(T->rchild);
int maxHeight = left>right?left:right;
return 1 + maxHeight;
}
}
int CountLeaf(BiTree T,int count)
{
if(T!=NULL)
{
if(T->lchild == NULL&&T->rchild == NULL)
count++;
count=CountLeaf(T->lchild,count);
count=CountLeaf(T->rchild,count);
}
return count;
}
Status BiTreeEmpty(BiTree T)
{ /* 初始条件:二叉树T存在。操作结果:若T为空二叉树,则返回TRUE,否则FALSE */
if(T)
return FALSE;
else
return TRUE;
}
TElemType Root(BiTree T)
{ //初始条件:二叉树T存在。操作结果:返回T的根
if(BiTreeEmpty(T))
return Nil;
else
return T->data;
}
void visitT(TElemType e)
{
printf("%c ",e);
}
void CopyTree(BiTree root, BiTree *newroot)
{
if(root)
{
*newroot = (BiTree)malloc(sizeof(BiTNode));
(*newroot)->data = root->data;
CopyTree(root->lchild,&((*newroot)->lchild));
CopyTree(root->rchild,&((*newroot)->rchild));
}
else *newroot = NULL;
}
void PreOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数。算法6.1,有改动 */
/* 操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次 */
if(T) /* T不空 */
{
Visit(T->data); /* 先访问根结点 */
PreOrderTraverse(T->lchild,Visit); /* 再先序遍历左子树 */
PreOrderTraverse(T->rchild,Visit); /* 最后先序遍历右子树 */
}
}
void main()
{
BiTree T,T1;
TElemType e1;
InitBiTree(&T);
InitBiTree(&T1);
printf("构造空二叉树后,树空否?%d(1:是 0:否)\n",BiTreeEmpty(T));
e1=Root(T);
if(e1!=Nil)
printf("二叉树的根为: %c\n",e1);
else
printf("树空,无根\n");
printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");
CreateBiTree(&T);
printf("建立二叉树后,树空否?%d(1:是 0:否) \n",BiTreeEmpty(T));
e1=Root(T);
if(e1!=Nil)
printf("二叉树的根为: %c",e1);
else
printf("树空,无根");
printf("该二叉树深度为:%d\n",getMaxDepth(T));
printf("该二叉树叶子结点个数为:%d\n",CountLeaf(T,0));
CopyTree(T,&T1);
DestroyBiTree(&T);
}