数据结构简单实验报告

  • 三种方法求阶乘
    /*---  1 利用阶乘的定义求解阶乘  ---*/
    #include<stdio.h>   
    void main(){ 
    	int i,n;     
    	long f=1;   
      	scanf("%d",&n);     
    	for(i=1;i<=n;i++)        
    	f=f*i;   
      	printf("%d!=%ld\n",n,f);     
    	getch();   
    }    
    /*--- 2  递归方法求阶乘  --- */   
    #include "stdio.h"   
    long fact(int n){  
    	long s;     
    	if(n<=1)   s=1;    
    	else
         	 s=n*fact(n-1);    
     	return s;   
    }    
    void main(){
    	int num;   
     	scanf("%d",&num);   
     	printf("%d!=%ld\n",num,fact(num));  
         	getch();  
     }   
    /*--- 3 利用静态变量求阶乘  ---*/   
    #include<stdio.h>  
    long fact(int n){ 
    	static long f=1;    
     	f=f*n;    
     	return f;         
    }  
     void main(){ 
    	int i;
       	for(i=1;i<=5;i++)   
           	printf("%d!=%ld\n",i,fact(i));  
    	getch();  
    }   
    
    实验结果:

 

  • 斐波那契数列的四种实现方式 
    1.递归
    int Fibon1(int n){
    if (n == 1 || n == 2)   return 1;
    else   return Fibon1(n - 1) + Fibon1(n - 2);
    }
    int main(){
    	int n = 0;
    	int ret = 0;
    	scanf("%d", &n);
    	ret = Fibon1(n);
    	printf("ret=%d\n", ret);
    	return 0;
    }
    2.非递归
    int Fibno2(int n){
    	int num1 = 1;
    	int num2 = 1;
    	int tmp = 0;
    	int i = 0;
    	if (n < 3) return 1;
    	else
    	{
    		for (i = 0; i>n-3; i++)
    		{
    			tmp = num1 + num2;
    			num1 = num2;
    			num2 = tmp;
    		}
    		return tmp;
    	}
    }
    3.数组
    public  int Fibno3(int n){
    	List<int> list = new List<int>();
    	list.fib(1);
    	list.fib(1);
    	int count = list.Count;
    	 while (count < n)
    		 {
    		        list.fib(list[count - 2] + list[count - 1]);
    		         count = list.Count;
    		  }
    		 return list[count - 1];
    	 }
    4.队列
    public int Fibno4(int n){
    	Queue<int> queue = new Queue<int>();
    	queue.Enqueue(1);
    	queue.Enqueue(1);
    	for (int i = 0; i <= n - 2; i++)
    	{
    	queue.Enqueue(queue.AsQueryable().First() + queue.AsQueryable().Last());
    		queue.Dequeue();
    	}
    	 return queue.Peek();
    }
    

    实验结果:

  • 简介:斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

  • 算法分析:                                                                                                                                                                               1.递归:求解F(n),必须先计算F(n-1)和F(n-2),计算F(n-1)和F(n-2),又必须先计算F(n-3)和F(n-4)。。。。。。以此类推,直至必须先计算F(1)和F(0),然后逆推得到F(n-1)和F(n-2)的结果,从而得到F(n)要计算很多重复的值,在时间上造成了很大的浪费,算法的时间复杂度随着N的增大呈现指数增长,时间的复杂度为O(2^n),即2的n次方。

从上图中不难发现:在这棵树中有很多结点是重复的,而且重复的结点数会随着n的增大而急剧增加,这意味计算量会随着n的增大而急剧增大。事实上,用递归方法计算的时间复杂度是以n的指数的方式递增的

2.非递归:从n(>2)开始计算,用F(n-1)和F(n-2)两个数相加求出结果,这样就避免了大量的重复计算,它的效率比递归算法快得多,算法的时间复杂度与n成正比,即算法的时间复杂度为O(n).

  • 顺序表基本操作

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<ctype.h>
#define maxsize 26
#define stepsize 10
#define ok 1
#define Error -1
#define overflow 0
typedef int Elemtype;
typedef struct{
	Elemtype *elem;
	int length;
}Sqlist;
void InitList(Sqlist &L);
void listshow(Sqlist *L);
void main()
{
	Sqlist L;
	InitList(L);
	for(int i=0;i<26;i++)
	{
		L.elem[i]=i+97;
		printf("%c\t",L.elem[i]);
		if(i%5==0&&i!=0) printf("\n");
}
	system("pause");

}
//1.顺序表初始化 
void InitList( Sqlist &L ){
	L.elem=(Elemtype*)malloc(sizeof(Elemtype)*maxsize);
	if(!L.elem) {
	printf("顺序表初始化失败");
		exit(overflow);
	}
	else
	printf("顺序表初始化成功\n");
	L.length=0;
}
//2.销毁顺序表
 void destorylist(Sqlist *L){
 	if(!L->elem)
 	printf("顺序表不存在!无法执行操作");
 	else
 	{
	free(L->elem); 
	 printf("顺序表已经销毁");
	}
  } 
  //3.清空顺序表
  void clearlist(Sqlist *L){
  	if(!L->elem)
 	printf("顺序表不存在!无法执行操作");
 	else
 	{
	 L->length=0; 
	 printf("顺序表已经清空");
	}
  } 
  //4.返回顺序表长度
   int listlength(Sqlist *L){
   	if(!L->elem)
 	{printf("顺序表不存在!无法执行操作");
	return Error;}
 	else{ 
	 printf("顺序表已经清空");
	 return L->length;
	}
	}
	//5.在第i个位置插入数据
	int listinsert(Sqlist *L,int i, Elemtype e){
		int j;
		if(!L->elem){
 		printf("顺序表不存在!无法执行操作");
		return Error;}
 	else
 	{
 		if(L->length>=maxsize){
 			L->elem=(Elemtype*)realloc(L->elem,sizeof(Elemtype)*stepsize);
		 }
	 if(i>0&&i<=L->length+1){
	 	for(j=L->length;j>=i;j--)
	 	L->elem[j]=L->elem[j-1];
	 	L->elem[i-1]=e;
	 	L->length++;
	 }
	}
	}
	//6.删除第i个元素
	int listdelete(Sqlist *L,int i,Elemtype &e){
		int j;
		if(!L->elem){
 	printf("顺序表不存在!无法执行操作");
		return Error;}
 	else
 	{
	 if(i>0&&i<=listlength(L)){
	 	e=L->elem[i-1];
	 	for(j=i;j<=listlength(L);j++)
	 	L->elem[j-1]=L->elem[j];
	 	L->length--;
	 	printf("删除成功");
	 }
	}
	} 
	//7.显示顺序表
	void listshow(Sqlist *L){
		int i;
		printf("打印长度为%d的顺序表",L->length);
		for(i=0;i<L->length;i++)
		printf("%c",L->elem[i]);
	} 

实验结果: 使用顺序表输出了26个小写的英文字母

 

  • 链表基本操作
#include <stdio.h>
#include <stdlib.h>
typedef struct Link{
	int elem;
	struct Link *next;
}link;
link * initLink();
//链表插入的函数,p是链表,elem是插入的结点的数据域,add是插入的位置
link * insertElem(link * p,int elem,int add);
//删除结点的函数,p代表操作链表,add代表删除节点的位置
link * delElem(link * p,int add);
//查找结点的函数,elem为目标结点的数据域的值
int selectElem(link * p,int elem);
//更新结点的函数,newElem为新的数据域的值
link *amendElem(link * p, int add, int newElem);
void display(link *p);
int main() {
  //初始化链表(1,2,3,4)
  printf("初始化链表为:\n");
link *p = initLink();
display(p);
  printf("在第4的位置插入元素5:\n");
  p = insertElem(p, 5, 4);
  display(p);
  printf("删除元素3:\n");
p = delElem(p, 3);
display(p);
printf("查找元素2的位置为:\n");
  int address = selectElem(p, 2);
  if (address == -1) 
    printf("没有该元素");
  else
    printf("元素2的位置为:%d\n",address);
  printf("更改第3的位置的数据为7:\n");
  p = amendElem(p, 3, 7);
display(p);
return 0;
}
link * initLink(){
  link * p = (link*)malloc(sizeof(link));//创建一个头结点
  link * temp = p;//声明一个指针指向头结点,用于遍历链表
  //生成链表
  for (int i=1; i<5; i++) 
  {
    link *a = (link*)malloc(sizeof(link));
    a->elem=i;
	a->next=NULL;
    temp->next=a;
    temp=temp->next;
  }
 return p;
}
link *insertElem(link * p, int elem, int add){
  link * temp = p;  //创建临时结点temp
  //首先找到要插入位置的上一个结点
  for (int i=1; i<add; i++) 
  {
    if (temp == NULL) 
    {
     printf("插入位置无效\n");
     return p;
    }
  temp = temp->next;
}
  //创建插入结点c
  link * c = (link*)malloc(sizeof(link));
  c->elem = elem;
  //向链表中插入结点
  c->next = temp->next;
  temp->next = c;
  return p;
}
link * delElem(link * p, int add){
  link * temp = p;
  //遍历到被删除结点的上一个结点
  for (int i=1; i<add; i++) 
  {
    temp = temp->next;
  }
  link * del = temp->next;    //单独设置一个指针指向被删除结点,以防丢失
  temp->next = temp->next->next;  //删除某结点就是更改前一个结点的指针域
  free(del);    //手动释放该结点,防止内存泄漏
  return p;
}
int selectElem(link * p, int elem){
  link *t = p;
  int i = 1;
  while (t->next) 
  {
    t = t->next;
    if (t->elem == elem)  
      return i;
    i++;
  }
return -1;
}
link *amendElem(link * p, int add, int newElem){
  link * temp = p;
  temp = temp->next;  //tamp指向首元结点
  //temp指向被删除结点
  for (int i=1; i<add; i++) 
  	temp = temp->next;
   temp->elem = newElem;
   return p;
}
void display(link *p){
  link* temp = p;//将temp指针重新指向头结点
  //只要temp指针指向的结点的next不是Null,就执行输出语句。
  while (temp->next) 
  {
    temp = temp->next;
    printf("%d", temp->elem);
  }
  printf("\n");
}

实验结果: 

 

  •  顺序栈基本操作
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
typedef struct node* SeqStack;
typedef char ElementType;
struct node {
    ElementType data[MaxSize];
    int top;  //标记栈顶数据  
};
//初始化
void InitNode(SeqStack *L) {
    (*L) = (SeqStack)malloc(sizeof(struct node));
    (*L)->top = -1;
}
//进栈
void PushStack(SeqStack L, ElementType x) {
    if (L->top == MaxSize - 1) {
        printf("满了");
    }
    else {
        L->top++;  //入栈所以加1
        L->data[L->top] = x;
    }
}
//出栈
void PopStack(SeqStack L, ElementType *x) {
    if (L->top == -1) {
        printf("空的");
    }
    else {
        *x = L->data[L->top];
        L->top--;
    }
}
//遍历输出
void PrintNode(SeqStack L) {
    for (int i = 0; i <= L->top; i++) {
        printf("%c", L->data[i]);
    }
    printf("\n");
}
int main() {
    SeqStack s;
    ElementType c;
    ElementType* y;
    y = &c;  //y指向c,为了出栈用
    InitNode(&s);
    printf("输入入栈数据");
    scanf("%c", &c);
    while (c != '\n') {
        PushStack(s, c);
        scanf("%c", &c);
    }
    PrintNode(s);
    PopStack(s, y);
    printf("出栈元素是%c\n", *y);
    PrintNode(s);
}

实验结果: 

  • 链栈基本操作 
#include<stdio.h>
#include<stdlib.h>
typedef char ElementType;
typedef struct node* LinkStack;
struct node {
    ElementType data;
    LinkStack next;
};
//初始化
void InitLinkStack(LinkStack *L) {
    (*L) = NULL;
}
//入栈
void PushStack(LinkStack *L, ElementType x) {
    LinkStack s;
    s = (LinkStack)malloc(sizeof(struct node));
    s->data = x;
    s->next = (*L); //L是栈顶元素
    (*L) = s;  //s成为新的栈顶元素
}
//出栈
void PopStack(LinkStack *L, ElementType *x) {
    if ((*L)->next == NULL) {
        printf("空栈");
    }
    else {
        LinkStack p;
        *x = (*L)->data;
        p = (*L);  //标记栈顶
        (*L) = (*L)->next;
        free(p); //出栈
    }
}
//判断栈空
int LinkStack_Empty(LinkStack top){
	if(top->next == NULL)//如果栈顶的指针域指向空,则栈空
		return 1;
	else  
		return 0;
}
//取栈顶元素
int Get_LinkStack(LinkStack top, ElementType *x){
	if(top->next == NULL)
		return 0;
	else
	{
		*x = top->next->data;
		return 1;
	}
}
void PrintNode(LinkStack L) {
    while (L != NULL) {
        printf("%c", L->data);
        L = L->next;
    }
    printf("\n");
}
int main() {
    LinkStack s;
    ElementType c;
    ElementType* y;
    y = &c; 
    InitLinkStack(&s);
    printf("入栈元素为:\n");
    scanf("%c", &c);
    while (c != '\n') {
        PushStack(&s, c);
        scanf("%c", &c);
    }
    PrintNode(s);
    PopStack(&s, y);
    printf("出栈元素为:%c\n", *y);
    printf("栈中剩余元素为:\n");
    PrintNode(s);
}

实验结果: 

  • 顺序队列基本操作
#include<stdio.h>
#include<stdlib.h>
 
#define MAX	1000
typedef struct
{
	int data[MAX];
	int front;
	int rear;
}SeQueue;
 
void InitQueue(SeQueue *SQ)
{
	SQ->front=SQ->rear=0;
}
 
int EmptyQueue(SeQueue *SQ)
{
	if(SQ->front==SQ->rear)
	{
		printf("\n队空!\n");
		return 1;
	}
	return 0;
}
 
int GetFront(SeQueue *SQ, int *x)
{
	if(EmptyQueue(SQ))
	{
		printf("队空!\n");
		return 0;
	}
	*x=SQ->data[(SQ->front+1)%MAX];
	return 1;
}
 
int EnQueue(SeQueue *SQ, int x)
{
	if(SQ->front==(SQ->rear+1)%MAX)
	{
		printf("队满!\n");
		return 0;
	}
	SQ->rear=(SQ->rear+1)%MAX;
	SQ->data[SQ->rear]=x;
	return 1;
}
 
int OutQueue(SeQueue *SQ, int *x)
{
	if(EmptyQueue(SQ))
	{
		printf("队空!\n");
		return 0;
	}
	SQ->front=(SQ->front+1)%MAX;
	*x=SQ->data[SQ->front];
	return 1;
}
 
int main()
{
	SeQueue *Q;
	Q=(SeQueue *)malloc(sizeof(SeQueue));
	int x, fx;
	int n;
	int j;
	InitQueue(Q);
	printf("输入入队元素个数n:\n");
	scanf("%d", &n);
	for(int i=1; i<=n; i++)
	{
		EnQueue(Q, i);
	}
	GetFront(Q, &fx);
	printf("队头元素:%d\n", fx);
	printf("输出队列元素:\n");
	for(j=Q->front+1;j<=Q->rear;j=(j+1)%MAX)
	{
		printf("%3d",Q->data[j]);	
	}
 
	for(int i=1; i<=n; i++)
	{
		OutQueue(Q, &x);
		printf("\n出队元素:%d\n", x);
	}
	system("pause");
	return 0;
}

实验结果: 

 

  • 循环队列基本操作
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#define MaxSize 10
typedef int DataType;
typedef struct SeqQueue{
    DataType Queue[MaxSize];
    int fornt;
    int rear;
}SeqCirQueue;
//队列初始化
void InitSeqCirQueue(SeqCirQueue* SCQ){
    SCQ->fornt = SCQ->rear = 0;
}
//判断队列是否为空
int IsEmpty(SeqCirQueue* SCQ){
    if (SCQ->fornt == SCQ->rear)
        return 1;
    return 0;
}
//判断队列是否为满
int IsFull(SeqCirQueue* SCQ){
    //尾指针+1追上队头指针,标志队列已经满了
    if ((SCQ->rear + 1) % MaxSize == SCQ->fornt)
        return 1;
    return 0;
}
//入队操作
int EnterSeqCirQueue(SeqCirQueue* SCQ, DataType data){
    if (IsFull(SCQ))
    {
        printf("队列已满,不能入队!\n");
        return 0;
    }
    SCQ->Queue[SCQ->rear] = data;
    SCQ->rear = (SCQ->rear + 1) % MaxSize;   //重新设置队尾指针
}
//出队操作
int DeleteSeqCirQueue(SeqCirQueue* SCQ,DataType* data){
    if (IsEmpty(SCQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    *data = SCQ->Queue[SCQ->fornt];
    SCQ->fornt = (SCQ->fornt + 1) % MaxSize;  //重新设置队头指针
}
//取队首元素
int GetHead(SeqCirQueue* SCQ,DataType* data){
    if (IsEmpty(SCQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    *data = SCQ->Queue[SCQ->fornt];
    return *data;
}
//清空队列
void ClearSeqCirQueue(SeqCirQueue* SCQ){
    SCQ->fornt = SCQ->rear = 0;
}
//打印队列元素
void PrintSeqCirQueue(SeqCirQueue* SCQ){
    assert(SCQ);   //断言SCQ不为空
    int i = SCQ->fornt;
    if (SCQ->fornt < SCQ->rear)
    {
        for (; i < SCQ->rear; i++)
        {
            printf("%-3d", SCQ->Queue[i]);
        }
    }
    else
    {
        for (i; i <SCQ->rear + MaxSize; i++)
        {
            printf("%-3d", SCQ->Queue[i]);
        }
    }
    printf("\n");
}
int main(){
    SeqCirQueue SCQ;
    DataType data;
    //初始化队列
    InitSeqCirQueue(&SCQ);
    //入队
    EnterSeqCirQueue(&SCQ, 1);
    EnterSeqCirQueue(&SCQ, 2);
    EnterSeqCirQueue(&SCQ, 4);
    EnterSeqCirQueue(&SCQ, 6);
    EnterSeqCirQueue(&SCQ, 8);
    EnterSeqCirQueue(&SCQ, 9);
    EnterSeqCirQueue(&SCQ, 10);
    EnterSeqCirQueue(&SCQ, 12);
    EnterSeqCirQueue(&SCQ, 13);
    printf("队列中元素为:\n");
    //打印队列中元素
    PrintSeqCirQueue(&SCQ);
    EnterSeqCirQueue(&SCQ, 15);
    //出队
    DeleteSeqCirQueue(&SCQ, &data);
    printf("出队元素为:%d\n", data);
    printf("\n");
    printf("队列中元素为:\n");
    PrintSeqCirQueue(&SCQ);
    printf("15入队:\n");
    EnterSeqCirQueue(&SCQ, 15);
    printf("队列中元素为:\n");
    PrintSeqCirQueue(&SCQ);
    system("pause");
    return 0;
}

实验结果: 

  • 链队基本操作 
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <assert.h>
typedef int DataType;
typedef struct Node{
    DataType _data;
    struct Node* _next;
}LinkQueueNode;
typedef struct{
    LinkQueueNode* front;
    LinkQueueNode* rear;
}LinkQueue;
//初始化队列
void InitLinkQueue(LinkQueue* LQ){
    //创建一个头结点
    LinkQueueNode* pHead = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    assert(pHead);
    LQ->front = LQ->rear = pHead; //队头和队尾指向头结点
    LQ->front->_next = NULL;
}
//判断队列是否为空
int IsEmpty(LinkQueue* LQ){
    if (LQ->front->_next == NULL)
    {
        return 1;
    }
    return 0;
}
//入队操作
void EnterLinkQueue(LinkQueue* LQ, DataType data){
    //创建一个新结点
    LinkQueueNode* pNewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    assert(pNewNode);
    pNewNode->_data = data;  //将数据元素赋值给结点的数据域
    pNewNode->_next = NULL;  //将结点的指针域置空
    LQ->rear->_next = pNewNode;   //将原来队列的队尾指针指向新结点
    LQ->rear = pNewNode;      //将队尾指针指向新结点
}
//出队操作
void DeleteLinkQueue(LinkQueue* LQ,DataType* data){
    if (IsEmpty(LQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    //pDel指向队头元素,由于队头指针front指向头结点,所以pDel指向头结点的下一个结点
    LinkQueueNode* pDel = LQ->front->_next;  
    *data = pDel->_data;   //将要出队的元素赋给data
    LQ->front->_next = pDel->_next;  //使指向头结点的指针指向pDel的下一个结点
    //如果队列中只有一个元素,将队列置空
    if (LQ->rear = pDel)   
    {
        LQ->rear = LQ->front;
    }
    free(pDel);   //释放pDel指向的空间
}
//取队头元素
int GetHead(LinkQueue* LQ, DataType* data){
    if (IsEmpty(LQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    LinkQueueNode* pCur;
    pCur = LQ->front->_next;  //pCur指向队列的第一个元素,即头结点的下一个结点
    *data = pCur->_data;      //将队头元素值赋给data
    return *data;             //返回队头元素值
}
//清空队列
void ClearQueue(LinkQueue* LQ){
    while (LQ->front != NULL)
    {
        LQ->rear = LQ->front->_next;  //队尾指针指向队头指针的下一个结点
        free(LQ->front);              //释放队头指针指向的结点
        LQ->front = LQ->rear;         //队头指针指向队尾指针
    }
}
//打印队列中的元素
void PrintLinkQueue(LinkQueue* LQ){
    assert(LQ);
    LinkQueueNode * pCur;
    pCur = LQ->front->_next;
    while (pCur)
    {
        printf("%-3d", pCur->_data);
        pCur = pCur->_next;
    }
    printf("\n");
}
int main(){
    LinkQueue LQ; 
    DataType data;
    //初始化队列
    InitLinkQueue(&LQ);
    //入队
    EnterLinkQueue(&LQ, 1); 
    EnterLinkQueue(&LQ, 2);
    EnterLinkQueue(&LQ, 3);
    EnterLinkQueue(&LQ, 4);
    EnterLinkQueue(&LQ, 5);
    EnterLinkQueue(&LQ, 6);
    EnterLinkQueue(&LQ, 7);
    EnterLinkQueue(&LQ, 8);
    printf("队列中的元素为:");
    //打印队列中元素
    PrintLinkQueue(&LQ);
    printf("\n");
    //取队头元素
    data = GetHead(&LQ, &data);
    printf("队头元素为:%d\n", data);
    printf("\n");
    //出队
    DeleteLinkQueue(&LQ, &data);
    printf("出队的元素为:%d\n", data);
    printf("\n");
    printf("队列中的元素为:");
    PrintLinkQueue(&LQ);
    printf("\n");
    data = GetHead(&LQ, &data);
    printf("队头元素为:%d\n", data);
    printf("\n");
    ClearQueue(&LQ);
    system("pause");
    return 0;
}

实验结果: 

  • 二叉树基本操作
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#define MAXTSIZE 1000
using namespace std;

/* 
测试数据: abc##de#g##f###
*/

typedef struct BiTNode
{
    char data; // 结点数据域 
    struct BiTNode *lchild,*rchild; // 左右孩子指针 
}BiTNode,*BiTree;

void CreateBiTree(BiTree &T) // 先序遍历建立二叉链表 
{
    char ch;
    cin>>ch;
//    scanf("%c",&ch);
    if(ch=='#')
        T=NULL;
    else
    {
        T=(BiTNode *)malloc(sizeof(BiTNode));
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}

void travel1(BiTree T) // 先序遍历 
{
    if(T)
    {
        printf("%c",T->data);
        travel1(T->lchild);
        travel1(T->rchild);
    }
}

void travel2(BiTree T) // 中序遍历 
{
    if(T)
    {
        travel2(T->lchild);    
        printf("%c",T->data);
        travel2(T->rchild);
    }
}

void travel3(BiTree T) // 后序遍历 
{
    if(T)
    {
        travel3(T->lchild);
        travel3(T->rchild);
        printf("%c",T->data);
    }
}

int count(BiTree T) // 计算叶子结点的个数 
{
    if(T==NULL)    return 0;
    int cnt=0;
    if((!T->lchild)&&(!T->rchild))
    {
        cnt++;
    }
    int leftcnt=count(T->lchild);
    int rightcnt=count(T->rchild);
    cnt+=leftcnt+rightcnt;
    return cnt;
}

int Depth(BiTree T) // 计算二叉树的深度 
{
    if(T==NULL)    return 0;
    else
    {
        int m=Depth(T->lchild);
        int n=Depth(T->rchild);
        return m>n?(m+1):(n+1);
    }
}

void exchange(BiTree T,BiTree &NewT) // 交换左右子树 
{
    if(T==NULL)
    {
        NewT=NULL;
        return ;
    }
    else
    {
        NewT=(BiTNode *)malloc(sizeof(BiTNode));
        NewT->data=T->data;
        exchange(T->lchild,NewT->rchild); // 复制原树的左子树给新树的右子树 
        exchange(T->rchild,NewT->lchild); // 复制原树的右子树给新树的左子树 
    }
}

int main()
{
    puts("**************************");
    puts("1. 建立二叉树"); 
    puts("2. 先序遍历二叉树");
    puts("3. 中序遍历二叉树");
    puts("4. 后序遍历二叉树");
    puts("5. 计算叶子结点个数"); 
    puts("6. 计算二叉树的深度"); 
    puts("7. 交换二叉树的左右子树"); 
    puts("0. 退出");
    puts("**************************");
    BiTree Tree,NewTree;
    int choose;
    while(~scanf("%d",&choose),choose)
    {
        switch(choose)
        {
            case 1:
                puts("温馨提醒:输入请以 '#' 为左/右子树空的标志!"); 
                CreateBiTree(Tree);
                break;
            case 2:
                printf("先序遍历结果为:"); 
                travel1(Tree);
                puts("");
                break;
            case 3:
                printf("中序遍历结果为:"); 
                travel2(Tree);
                puts("");
                break;
            case 4:
                printf("后序遍历结果为:"); 
                travel3(Tree);
                puts("");
                break;
            case 5:
                printf("叶子结点个数为:%d\n",count(Tree));
                break;
            case 6:
                printf("二叉树的深度为:%d\n",Depth(Tree));
                break;
            case 7:
                exchange(Tree,NewTree);
                Tree=NewTree;
                puts("交换成功!\n"); 
                break;
        }
    }
    system("pause");
    return 0;
}

实验结果: 

 链接:https://pan.baidu.com/s/1SR06RHD0iX7VVCpWvM6NtQ 
提取码请通过评论获取。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值