数据结构基本操作C语言带截图(非伪代码,可直接运行



前言

纸上得来终觉浅,理论看着很简单,实际操作还是遇到了不小的困难,以下所有程序都可以在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);
   
 }

在这里插入图片描述

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值