数据结构实验报告

时间:2024.4.13

课程名称:          数据结构          

专业班级:             

    号:       

    名:                

指导教师:             

报告日期:              

计算机科学与技术学院

 

1 课程实验概述............................................................................................................... 1

2 实验一 基于顺序结构的线性表实现

2.1 问题描述............................................................................................................ 2

2.2 系统设计............................................................................................................ 2

2.3 系统实现............................................................................................................ 2

2.4 效率分析............................................................................................................ 2

3 实验二 基于链式结构的线性表实现

3.1 问题描述............................................................................................................ 3

3.2 系统设计............................................................................................................ 3

3.3 系统实现............................................................................................................ 3

3.4 效率分析............................................................................................................ 3

4 实验三 基于二叉链表的二叉树实现

4.1 问题描述............................................................................................................ 4

4.2 系统设计............................................................................................................ 4

4.3 系统实现............................................................................................................ 4

4.4 效率分析............................................................................................................ 4

5 实验总结与评价............................................................................................................ 5

1 课程实验概述

  本课程实验为数据结构试验,包括三个实验内容,实验目的在于: 

1.加深对数据结构和算法的理解,进一步提高学生编程能力; 

2.培养和提高学生分析问题与解决问题的综合能力; 

3.整理资料,撰写规范的实验报告。
2 实验一 基于顺序结构的线性表实现

2.1 问题描述

基于顺序存储结构,实现线性表的基本的、常见的运算。 实验要求: 

⑴ 提供一个实现功能的演示系统 

⑵ 具体物理结构和数据元素类型自行选定 

⑶ 线性表数据可以使用磁盘文件永久保存

2.2 系统设计

线性表的顺序存储表示:

typedef struct { 

ElemType *elem;    指针,指向顺序存放的一串数据元素     

int    length;      表长(实际数据元素个数) 

int    size;        表的大小(最多存贮数据元素个数)

 }SqList;

相关函数的算法思想描述:

 InitList(&L)    (创建表,此处是指表的初始化):

(1)申请存储数据元素空间 

  (2)置表长为0.

  DestroyList(&L)   (销毁表): 

(1)释放存储数据元素的空间置指针值为NULL。

  ClearList(&L)     (置表空): 

  (1)置表长为空(length=0)

  ListEmpty(L)      (判空): 

(1)若表长=0,返回TRUE,否则返回FALSE。

  ListLength(L)      (求表长): 

  (1)返回表长 

GetElem (L, i, &e)     (获取数据元素): 

(1)将第i单元值赋值给e 

LocateElem( L,e,compare( ) )    (查找数据元素) 

(1)按compare条件顺序查找e,若找到(第一次找到)返回对应位序,若未找到返回0 

PrioreElem( L, cur_e, &pre_e )   (获得前驱) 

(1)查找cur_e获取位序K 

(2)若K>1,将K-1号单元的元素赋值给pre_e并返回,否则返回ERROR。

 NextElem( L, cur_e, &next_e )   ( 获取后继): 

(1)查找cur_e, 获得位序K

(2)若K<表长,将K+1号元素值赋值给next_e并返回,否则返回ERROR。 

ListInsert( &L, i, e )       (插入数据元素): 

(1)移动元素,将位序为L.length ~ i 的数据元素顺序向后移动一个存储单元 

(2)插入新值,将e置入第i号存储单元 (3)修改表长,将表长加1 

ListDelete(&L, i, &e)     (删除数据元素): 

(1)获取返回值,将i号单元数据值赋给e返回 

(2)移动元素,将序号i+1 ~ L.length的数据元素顺序前移一个存储单元 (3)修改表长,将表长减1 

ListTraverse( L, visit( ) ) 

(1)调用visit函数顺序访问每一个数据元素,用L.length控制循环次数。

2.3 系统实现

相关结构及函数原型的说明(C语言描述)

/* Linear Table On Sequence Structure */

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define LIST_INIT_SIZE   100      /*线性表存储空间的初始分配量*/

#define LISTINCREMENT    10       /*线性表存储空间的分配增量*/

#define OVERFLOW         0

#define OK               1

#define TURE             1

#define FLASE            0

#define ERROR            0

/*------------------------------------------------------*/

typedef int status;

typedef struct{

       int item1;

}Elemtype;

typedef struct{

       Elemtype * elem;

       int length;

       int listsize;

}SqList;

/*------------------------------------------------------*/

status IntiaList(SqList * L);

status DestroyList(SqList * L);

status ClearList(SqList L);

status ListEmpty(SqList L);

int ListLength(SqList L);

status GetElem(SqList L,int i,Elemtype * e);

status LocatElem(SqList L,Elemtype e,status (* equal)(Elemtype x,Elemtype y));

status PriorElem(SqList L,Elemtype cur_e,Elemtype * pre_e);

status NextElem(SqList L,Elemtype cur_e,Elemtype * next_e);

status ListInsert(SqList *L,int i, Elemtype e);

status ListDelete(SqList *L,int i, Elemtype e);

status ListTrabverse(SqList L,void (* disply)(Elemtype e));

/*------------------------------------------------------*/

status equal(Elemtype x, Elemtype y);

void display(Elemtype e);

/*------------------------------------------------------*/

void menu(void);

/*------------------------------------------------------*/

void main(void){

       SqList L1,L2;

       int op=0;

       L1.elem=L2.elem=NULL;

       do{

               system("cls");

               menu();

               printf("          Please input your option[0-12]:");

               scanf("%d",&op);

               switch(op){

                      case 0:

                if(L1.elem){

                    printf("\tPlease destory L1 first!");

                    op=-1;

                    getchar();getchar();

                }

                else

                    printf("\n\t\tThe program is exiting");

                break;

                      case 1:

                if(IntiaList(&L1))

                    printf("\n     here is IntiaList(),which  being realized\n");

                else

                    printf("IntiaList()is failed!");

                getchar();getchar();

                break;

                      case 2:

                if(DestroyList(&L1))

                    printf("\n     here is DestroyList(),which  being realized\n");

                else

                    printf("DestroyList()is failed!");

                getchar();getchar();

                break;

                      case 3:

                if(ClearList(L1))

                    printf("here is ClearList(),which  being realized\n");

                else

                    printf("ClearList()is failed!");

                getchar();getchar();

                break;

                      case 4:

                if(ListEmpty(L1))

                    printf("\tThe list is empty\n");

                else

                    printf("\tThe list is not empty\n");

                                   getchar();getchar();

                    break;

                      case 5:

                    printf("\n     here is ListLength() ,which  being realized\n");

                    printf("             the listlength is %d",ListLength(L1));

                    getchar();getchar();

                    break;

                      case 6:

                {

                    int i=0;

                    Elemtype e;

                    printf("Please input the location:");

                    scanf("%d",&i);

                    if(GetElem(L1,i,&e))

                        printf("\tThe %dth elem is %d.\n",i,e);

                    else

                        printf("\tInvaild location.");

                    printf("\n     here is GetElem(),which  being realized\n");

                    getchar();getchar();

                    break;

                }

                      case 7:{

                Elemtype e;

                int n;

                printf("\tPlease input the item you want to find:");

                scanf("%d",&e);

                n=LocatElem(L1,e,equal);

                if(n)

                    printf("\t%d is the %dth item in L1",e,n);

                else

                    printf("\t%d is not in L1",e);

                printf("\n     here is LocatElem(),which  being realized\n");

                        getchar();getchar();

                        break;

                }

                      case 8:{

                Elemtype cur_e,pre_e;

                printf("\tPlease input the cur_e :");

                scanf("%d",&cur_e);

                if(PriorElem(L1,cur_e,&pre_e))

                    printf("the pre_e is: %d",pre_e);

                else

                    printf("Not Found!");

                       printf("\n     here is PriorElem(),which  being realized\n");

                                                  getchar();getchar();

                                                  break;

                }

                      case 9: {

                Elemtype cur_e,next_e;

                printf("\tPlease input the cur_e :");

                scanf("%d",&cur_e);

                if(NextElem(L1,cur_e,&next_e))

                    printf("the next_e is: %d",next_e);

                else

                    printf("Not Found!");

                printf("\n     here is NextElem(),which  being realized\n");

                                                  getchar();getchar();

                                                  break;

                }

                      case 10: {

                          Elemtype e;

                          int i;

                          printf("\tPlease input the item you want to insert:");

                          scanf("%d",&e);

                          printf("\tPlease input the position:");

                          scanf("%d",&i);

                          if(ListInsert(&L1,i,e))

                    printf("\tThe %d is insert at %d position.",e,i);

                else

                    printf("\tInsert failed!");

                printf("\n     here is ListInsert(),which  being realized\n");

                                                        getchar();getchar();

                                                        break;

                      }

                      case 11:{

                Elemtype e;

                int i;

                printf("\tPlease input the position:");

                scanf("%d",&i);

                if(ListDelete(&L1,i,e))

                    printf("\tThe %dth item is deleted. ");

                else

                   printf("\tDelete failed.");

                printf("\n     here is ListDelete(),which  being realized\n");

                                                        getchar();getchar();

                                                        break;

                }

                      case 12: {printf("\n     here is ListTrabverse(),which  being realized\n");

                                                                if(!L1.elem)

                                                                              printf("\n     linear table L1 does not exist!\n");

                                                                       else if(!ListTrabverse(L1,display))

                                                                                                         printf("\n  this linear table is empty!\n");

                                                         getchar();getchar();

                                                         break;

                                                        }

                      default: ;

               }

       }while(op);

       getchar();getchar();

}

status IntiaList(SqList *L){

    /* 构造一个空的线性表*/

    L->elem=(Elemtype * )malloc(LIST_INIT_SIZE * sizeof(Elemtype));

    if(! L->elem) exit(OVERFLOW);

    L->length=0;

    L->listsize=LIST_INIT_SIZE;

    return OK;

}

status DestroyList(SqList *L){

    L->elem=NULL;

    L->listsize=0;

    return OK;

}

status ClearList(SqList L){

    L.length=0;

    return OK;

}

status ListEmpty(SqList L){

    if(L.length==0)

        return TURE;

    else

        return FLASE;

}

int ListLength(SqList L){

    return L.length;

}

status GetElem(SqList L,int i,Elemtype * e){

    if(i>L.length||i<1)

        return ERROR;

    *e=L.elem[i-1];

}

status LocatElem(SqList L,Elemtype e,status (* equal)(Elemtype ,Elemtype )){

    int i;

    i=1;

    Elemtype *p;

    p=L.elem;

    while(i<=L.length&&!(* equal)(*p++,e))   ++i;

    if(i<=L.length)   return i;

    else return 0;

}

status PriorElem(SqList L,Elemtype cur_e,Elemtype * pre_e){

    int i;

    for(i=1;i<L.length;i++)

        if((L.elem[i]).item1==cur_e.item1){

            *pre_e=L.elem[i-1];

            return 1;

            }

        return 0;

}

status NextElem(SqList L,Elemtype cur_e,Elemtype * next_e){

    int i;

    for(i=0;i<L.length-1;i++)

        if((L.elem[i]).item1==cur_e.item1){

            *next_e=L.elem[i+1];

            return 1;

            }

        return 0;

}

status ListInsert(SqList *L,int i, Elemtype e){

    if(i<1||i>L->length+1) return ERROR;

    Elemtype *newbase,*q,*p;

    if(L->length>=L->listsize){

        newbase=(Elemtype *)realloc(L->elem,(L->listsize+LISTINCREMENT)*sizeof(Elemtype));

        if(!newbase)exit(OVERFLOW);

        L->elem=newbase;

        L->listsize+=LISTINCREMENT;

        }

    q=&(L->elem[i]);

    for(p=&(L->elem[L->length]);p>=q;--p)  *(p+1)=*p;

    *p=e;

    L->length++;

    return OK;

}

status ListDelete(SqList *L,int i, Elemtype e){

    if((i<1)||(i>L->length))   return ERROR;

    Elemtype *p,*q;

    p=&(L->elem[i-1]);

    e=*p;

    q=L->elem+L->length-1;

    for(++p;p<=q;++p)  *(p-1)=*p;

    --L->length;

    return OK;

}

status ListTrabverse(SqList L, void (* disply)(Elemtype e)){

       int i;

       if(!L.length) return(0);

       printf("\n-------------all elements of linear table----------------\n");

       for(i=0;i<L.length;i++) display(L.elem[i]);

       return(1);

}

/*------------------------------------------------------*/

void menu(void){

       printf("\n\n");

       printf("      Menu for Linear Table On Sequence Structure \n");

       printf("------------------------------------------------------\n");

       printf("         1. IntiaList       7. LocatElem\n");

       printf("         2. DestroyList     8. PriorElem\n");

       printf("         3. ClearList       9. NextElem \n");

       printf("         4. ListEmpty      10. ListInsert\n");

       printf("         5. ListLength     11. ListDelete\n");

       printf("         6. GetElem        12. ListTrabverse\n");

       printf("         0. Exit\n");

       printf("------------------------------------------------------\n");

}

/*------------------------------------------------------*/

status equal(Elemtype x, Elemtype y){

       return (x.item1==y.item1);

}

void display(Elemtype e){

       printf("%d ",e.item1);

}

2.4 效率分析

分公司的

InitList(创建表,此处是指表的初始化): 

DestroyList(销毁表):  ClearList(置表空): ListEmpty(判空): ListLength(求表长): 

GetElem (L, i, &e)     (获取数据元素): 上述操作时间复杂度均为O(1)  

LocateElem( L,e,compare( ) )    (查找数据元素) T(n)=O(n)

PrioreElem( L, cur_e, &pre_e )   (获得前驱) T(n)=O(n)  

NextElem( L, cur_e, &next_e )   ( 获取后继): T(n)=O(n)  

ListInsert( &L, i, e )       (插入数据元素): ListDelete(&L, i, &e)     (删除数据元素):

删除和插入操作的时间主要耗费在移动元素上,而移动元素的个数取决于插入或删除的元素位置。 

假设pi是删除第i个元素的概率,则在长度为n的线性表中删除或插入一个元素所需移动元素的次数的期望值为 

删除:   插入:

若在任何位置插入或删除是等概率的,则:

插入:   删除:

则插入与删除的时间复杂度为O(n) 
         3 实验二 基于链式结构的线性表实现

3.1 问题描述

基于链式存储结构,实现线性表的基本的、常见的运算。 实验要求: 

⑴ 提供一个实现功能的演示系统 

⑵ 具体物理结构和数据元素类型自行选定

 ⑶ 线性表数据可以使用磁盘文件永久保存

3.2 系统设计

线性表的链式表式(具体使用时带头结点): 

typedef struct LNode{ 

    ElemType data;            数据域,存放数据元素 

struct LNode *next;        指针域,指向下一个结点(或为NULL) 

}LNode,* LinkList;

相关函数的算法思想描述: 

注:为操作方便采用带头结点的链表表示。

InitList(&L)(创建表,此处是指表的初始化): 

(1)头指针指向申请的一个存储结点,存储结点指针域赋值NULL。

DestroyList(&L)(销毁表): 

(1)释放所有结点包括头结点,头指针置为NULL。 ClearList(L)(置表空): 

(1)释放所有数据存储结点(不包括头结点),头结点指针域置为NULL。

 ListEmpty(L)(判空): 

(1)若头结点指针域为NULL则返回TRUE,否则返回FALSE。

 ListLength(L)(求表长): 

(1)指针p指向头结点 

(2)当p指向的结点的指针域非空时移动指针p,并统计移动次数n 

(3)返回移动次数n 

GetElem (L, i, &e)     (获取数据元素): 

(1)指针p指向头结点 

(2)将指针p移动i次,使指针p指向第i号单元 

(3)将第i单元值赋值给e并返回 

LocateElem( L,e,compare( ) )    (查找数据元素)

(1)指针p指向头结点,通过p=p->next,依次移动指针,访问数据域,用compare函数与e进行比较判断,并记录移动次数i 

(2)若第一次找到与e对应的结点数据域,返回移动次数i,若直至p=NULL,仍未找到,返回0 

PrioreElem( L, cur_e, &pre_e )   (获得前驱) 

(1)指针p指向头结点 

(2)通过p=p->next移动p,将指针pl指向其前驱,比较当前p所指结点数据域与cur_e 

(3)若相等且pl不是指向头结点,将pl所指结点数据域赋值给pre_e并返回,若相等但pl指向头结点返回ERROR;若访问至p=NULL,返回ERROR  

NextElem( L, cur_e, &next_e )   ( 获取后继): 

(1)依次移动指针p,比较p->data与cur_e

(2)若相等且p->next不等于null,将p->next->data赋值给next_e并返回,否则返回ERROR

ListInsert( L, i, e )       (插入数据元素): 

(1)指针定位,将指针p移至第i号数据存储结点的直接前驱 

(2)指针准备,将指针q指向新申请结点,其数据域由e赋值,

(3)修改结点指针域,q->next=p->next, p->next=p  

ListDelete(L, i, &e)     (删除数据元素):

(1)指针定位,将指针p移至第i号数据存储结点的直接前驱,q指向i号结点,将i号单元数据域值赋值给e 

(2)修改结点指针域,p->next=q->next 

(3)释放q所指结点空间 

ListTraverse( L, visit( ) ) 

 (1)调用visit函数依次访问每一个数据元素,p=p->next控制访问,p=null表示遍历结束。

3.3 系统实现

/* Linear Table On Link Structure */

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define OVERFLOW         0

#define OK               1

#define TURE             1

#define FLASE            0

#define ERROR            0

/*------------------------------------------------------*/

typedef int status;

typedef int Elemtype;

typedef struct LNode{

       Elemtype      data;

       struct LNode  *next;

}LNode,*Link;

typedef struct{

    Link head,tail;

    int length;

} LinkList;

/*------------------------------------------------------*/

status IntiaList(LinkList * L);

status DestroyList(LinkList * L);

status ClearList(LinkList *L);

status ListEmpty(LinkList  L);

int ListLength(LinkList L);

status GetElem(LinkList L,int i,Elemtype * e);

status LocatElem(LinkList L,Elemtype e,status (* equal)(Elemtype x,Elemtype y));

status PriorElem(LinkList *L,Elemtype cur_e,Elemtype * pre_e);

status NextElem(LinkList *L,Elemtype cur_e,Elemtype * next_e);

status ListInsert(LinkList *L,int i, Elemtype e);

status ListDelete(LinkList *L,int i, Elemtype e);

status ListTrabverse(LinkList L,void (* disply)(Elemtype e));

/*------------------------------------------------------*/

status equal(Elemtype x, Elemtype y);

void display(Elemtype e);

/*------------------------------------------------------*/

void menu(void);

/*------------------------------------------------------*/

void main(void){

       LinkList L1;

       L1.head=NULL;

       int op=0;

       do{

               system("cls");

               menu();

               printf("          Please input your option[0-12]:");

               scanf("%d",&op);

               switch(op){

                      case 0:

                if(L1.head){

                    printf("\tPlease destory L1 first!");

                    op=-1;

                    getchar();getchar();

                }

                else

                    printf("\n\t\tThe program is exiting");

                break;

                      case 1:

                if(IntiaList(&L1))

                    printf("\n     here is IntiaList(),which  being realized\n");

                else

                    printf("IntiaList()is failed!");

                getchar();getchar();

                break;

                      case 2:

                if(DestroyList(&L1))

                    printf("\n     here is DestroyList(),which  being realized\n");

                else

                    printf("DestroyList()is failed!");

                getchar();getchar();

                break;

                      case 3:

                if(ClearList(&L1))

                    printf("here is ClearList(),which  being realized\n");

                else

                    printf("ClearList()is failed!");

                getchar();getchar();

                break;

                      case 4:

                if(ListEmpty(L1))

                    printf("\tThe list is empty\n");

                else

                    printf("\tThe list is not empty\n");

                                   getchar();getchar();

                    break;

                      case 5:

                    printf("\n     here is ListLength() ,which  being realized\n");

                    printf("             the listlength is %d",ListLength(L1));

                    getchar();getchar();

                    break;

                      case 6:

                {

                    int i=0;

                    Elemtype e;

                    printf("Please input the location:");

                    scanf("%d",&i);

                    if(GetElem(L1,i,&e))

                        printf("\tThe %dth elem is %d.\n",i,e);

                    else

                        printf("\tInvaild location.");

                    printf("\n     here is GetElem(),which  being realized\n");

                    getchar();getchar();

                    break;

                }

                      case 7:{

                Elemtype e;

                int n;

                printf("\tPlease input the item you want to find:");

                scanf("%d",&e);

                n=LocatElem(L1,e,equal);

                if(n)

                    printf("\t%d is the %dth item in L1",e,n);

                else

                    printf("\t%d is not in L1",e);

                printf("\n     here is LocatElem(),which  being realized\n");

                        getchar();getchar();

                        break;

                }

                      case 8:{

                Elemtype cur_e,pre_e;

                printf("\tPlease input the cur_e :");

                scanf("%d",&cur_e);

                if(PriorElem(&L1,cur_e,&pre_e))

                    printf("the pre_e is: %d",pre_e);

                else

                    printf("Not Found!");

                       printf("\n     here is PriorElem(),which  being realized\n");

                                                  getchar();getchar();

                                                  break;

                }

                      case 9: {

                Elemtype cur_e,next_e;

                printf("\tPlease input the cur_e :");

                scanf("%d",&cur_e);

                if(NextElem(&L1,cur_e,&next_e))

                    printf("the next_e is: %d",next_e);

                else

                    printf("Not Found!");

                printf("\n     here is NextElem(),which  being realized\n");

                                                  getchar();getchar();

                                                  break;

                }

                      case 10: {

                          Elemtype e;

                          int i;

                          printf("\tPlease input the item you want to insert:");

                          scanf("%d",&e);

                          printf("\tPlease input the position:");

                          scanf("%d",&i);

                          if(ListInsert(&L1,i,e))

                    printf("\tThe %d is insert at %d position.",e,i);

                else

                    printf("\tInsert failed!");

                printf("\n     here is ListInsert(),which  being realized\n");

                                                        getchar();getchar();

                                                        break;

                      }

                      case 11:{

                Elemtype e;

                int i;

                printf("\tPlease input the position:");

                scanf("%d",&i);

                if(ListDelete(&L1,i,e))

                    printf("\tThe %dth item is deleted. ");

                else

                   printf("\tDelete failed.");

                printf("\n     here is ListDelete(),which  being realized\n");

                                                        getchar();getchar();

                                                        break;

                }

                      case 12: {printf("\n     here is ListTrabverse(),which  being realized\n");

                                                                if(!L1.head)

                                                                              printf("\n     linear table L1 does not exist!\n");

                                                                       else if(!ListTrabverse(L1,display))

                                                                                                         printf("\n  this linear table is empty!\n");

                                                         getchar();getchar();

                                                         break;

                                                        }

                      default: ;

               }

       }while(op);

       getchar();getchar();

}

status IntiaList(LinkList *L){

    /* 构造一个空的链表*/

    Link p;

    p=(Link)malloc(sizeof(LNode));

    if(!p) exit(OVERFLOW);

    p->next=NULL;

    L->head=L->tail=p;

    L->length=0;

    return OK;

}

status DestroyList(LinkList *L){

    Link p,q;

    p=L->head;

    q=L->head->next;

    free(p);

    p=q;

    while(p){

        q=q->next;

        free(p);

        p=q;

    }

    L->length=0;

    L->head=L->tail=NULL;

    return OK;

}

status ClearList(LinkList *L){

    Link p,q;

    p=q=L->head->next;

    while(p){

        q=q->next;

        free(p);

        p=q;

    }

    L->length=0;

    L->head=L->tail;

    return OK;

}

status ListEmpty(LinkList L){

    if(L.length==0)

        return TURE;

    else

        return FLASE;

}

int ListLength(LinkList L){

    return L.length;

}

status GetElem(LinkList L,int i,Elemtype *e){

    Link p=L.head;

    int j=1;

    if(i>L.length||i<1) return ERROR;

    for(j=0;j<i;j++)

        p=p->next;

    *e=p->data;

    return OK;

}

status LocatElem(LinkList L,Elemtype e,status (* equal)(Elemtype ,Elemtype )){

    Link p=L.head;

    int i=0;

    do{

        p=p->next;

        i++;

    }while(p&&!equal(p->data,e));

    return i;

}

status PriorElem(LinkList *L,Elemtype cur_e,Elemtype * pre_e){

    Link p,q;

    p=L->head->next;

    while(p->next)

    {

       q=p->next;

       if(q->data==cur_e)  {

            *pre_e=p->data;

            return OK;

       }

       p=q;

    }

    return 0;

}

status NextElem(LinkList *L,Elemtype cur_e,Elemtype * next_e){

    Link p,q;

    p=L->head->next;

    while(p->next)

    {

       q=p->next;

       if(p->data==cur_e)  {

            *next_e=q->data;

            return OK;

       }

       p=q;

    }

    return 0;

}

status ListInsert(LinkList *L,int i, Elemtype e){

    Link p,s;

    p=L->head;

    int j=0;

    while(p&&j<i-1){p=p->next;++j;}

    if(!p||j>i-1) return ERROR;

    s=(Link)malloc(sizeof(LNode));

    s->data=e;s->next=p->next;

    p->next=s;

    L->length++;

    return OK;

}

status ListDelete(LinkList *L,int i, Elemtype e){

    Link p,q;

    p=L->head;

    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);

    L->length--;

    return OK;

}

status ListTrabverse(LinkList L, void (* disply)(Elemtype e)){

       int i;

       Link p=L.head->next;

       if(!L.length) return(0);

       printf("\n-------------all elements of linear table----------------\n");

       for(i=0;i<L.length;i++){

        disply(p->data);

        p=p->next;

       }

       return OK;

}

/*------------------------------------------------------*/

void menu(void){

       printf("\n\n");

       printf("      Menu for Linear Table On Sequence Structure \n");

       printf("------------------------------------------------------\n");

       printf("         1. IntiaList       7. LocatElem\n");

       printf("         2. DestroyList     8. PriorElem\n");

       printf("         3. ClearList       9. NextElem \n");

       printf("         4. ListEmpty      10. ListInsert\n");

       printf("         5. ListLength     11. ListDelete\n");

       printf("         6. GetElem        12. ListTrabverse\n");

       printf("         0. Exit\n");

       printf("------------------------------------------------------\n");

}

/*------------------------------------------------------*/

status equal(Elemtype x, Elemtype y){

       return (x==y);

}

void display(Elemtype e){

       printf("%d ",e);

}

3.4 效率分析

主要分析插入和删除的时间复杂度: 

插入: 

假设线性表长度为n,在第i个之前插入的概率为pi ,则插入运算指针移动次数的数学期望为:

 在等概率下, 

平均时间复杂度:O(n) 

最好情况时间复杂度:O(1) 

最坏情况时间复杂度:O(n)  

删除: 

假设线性表长度为n,删除第i个结点的概率为pi ,则删除运算指针移动次数的数学期望为:  在等概率下, 

平均时间复杂度:O(n) 

最好情况时间复杂度:O(1)

最坏情况时间复杂度:O(n)
             4 实验三 基于二叉链表的二叉树实现

4.1 问题描述

基于二叉链表,实现二叉树的下列运算: 

                             ① 二叉树生成;

                        ② 前序、中序和后序遍历;                           

                ③ 计算叶子数目;                         

                 ④ 按层次遍历;                           

                ⑤ 求二叉树高度; 实验要求: 

⑴ 提供一个实现功能的演示系统 

⑵ 具体物理结构和数据元素类型自行选定 

⑶ ②、③和⑤运算分别采用递归和非递归算法实现

4.2 系统设计

相关函数的算法思想描述: 递归实现的操作定义: 

前序遍历: 

若二叉树为空,则空操作,否则: 

(1)访问根结点 

(2)前序遍历左子树 

(3)前序遍历右子树 中序遍历: 

若二叉树为空,则空操作,否则: 

(1)中序遍历左子树 

  (2)访问根结点 

(3)中序遍历右子树 后序遍历:

若二叉树为空,则空操作,否则: 

  (1)后序遍历左子树 

  (2)后序遍历右子树 

  (3)访问根结点 求树深: 

若二叉树未空,返回树深0,否则: 

(1)返回1+MAX[对左子树求树深的返回值,对右子树求树深的返回值

(2)对左子树求树深

(3)对右子树求树深

求叶子数目: 

(1)若二叉树为空返回0,否则转(2) 

(2)若二叉树左右子树为空,返回1,否则转(3) 

(3)返回对“左子树求叶子数目”的的返回值+“对左子树求叶子数目”的返回值 

(4)对左子树求叶子数目 

(5)对右子树求叶子数目 

4.3 系统实现

相关代码如下:

/*-------------------BiTree-------------------*/

#include <stdio.h>

#include <stdlib.h>

/*--------------------------------------------*/

#define TRUE    1

#define FALSE   0

#define ERROR   -1

#define STACK_INIT_SIZE 100

#define STACKINCREMENT 10

#define MAXQSIZE 100

#define BiTreeSp 7

#define BiTreeSpInput 3

#define MAX 100

/*--------------------------------------------*/

typedef int Status;

typedef struct ElemType{

    char data;

}TElemType;

typedef struct BiTNode{

    TElemType elem;

    struct BiTNode *lchild,*rchild;

}BiTNode;

typedef BiTNode * SElemType;

typedef struct SqStack{

       SElemType *base;

       SElemType *top;

       int stacksize;

}SqStack;

typedef BiTNode * QElemType;

typedef struct SqQueue{

       QElemType *base;

       int front;

       int rear;

}SqQueue;

enum definition {PreOrder,InOrder,PostOrder,LevelOrder};

/*--------------------------------------------*/

//BiTree

//NO.1

Status CreatBiTree(BiTNode ** T,char *s,int *num);

//NO.2

Status PreOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e));

Status InOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e));

Status PostOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e));

//NO.3

Status BiTreeLeaf(BiTNode * T);

//NO.4

Status LevelOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e));

//NO.5

Status BiTreeDepth(BiTNode * T);

//Others

Status menu(void);

Status Visit(TElemType e);

Status DisplayOutput(BiTNode *T);

Status DisplayInput(char *s,int num);

Status InitStack(SqStack *s);

Status Push(SqStack *s,SElemType e);

Status Pop(SqStack *s,SElemType *e);

Status InitQueue(SqQueue *q);

Status En(SqQueue *q,QElemType e);

Status De(SqQueue *q,QElemType *e);

Status Save(BiTNode *T);

Status Open(BiTNode **T);

Status WriteBiTree(BiTNode **T,char *s,int *i);

/*--------------------------------------------*/

int main(void){

    BiTNode *T=NULL;

       char s[MAX];int num=0;

    int op;

    do{

        system("cls");

              if(num)DisplayInput(s,num);

              DisplayOutput(T);

        menu();

        printf("please input your option[0-9]: ");

        scanf("%d",&op);

              putchar('\n');

              getchar(); //get the line break

        switch(op){

            case 0:break;

            case 1:printf("\nThere is CreatBiTree(), which is been realized!\n");

                CreatBiTree(&T,s,&num);getchar();

                            break;

                     case 2:printf("\nThere is PreOrderTraverse(), which is been realized!\n");

                            PreOrderTraverse(T,Visit);getchar();

                            break;

                     case 3:printf("\nThere is InOrderTraverse(), which is been realized!\n");

                            InOrderTraverse(T,Visit);getchar();

                            break;

                     case 4:printf("\nThere is PostOrderTraverse(), which is been realized!\n");

                            PostOrderTraverse(T,Visit);getchar();

                            break;

                     case 6:printf("\nThere is BiTreeLeaf(), which is been realized!\n");

                            BiTreeLeaf(T);getchar();

                            break;

                     case 5:printf("\nThere is LevelOrderTraverse(), which is been realized!\n");

                            LevelOrderTraverse(T,Visit);getchar();

                            break;

                     case 7:printf("\nThere is BiTreeDepth(), which is been realized!\n");

                            printf("\nThe depth of the BiTree is %d",BiTreeDepth(T));getchar();

                            break;

                     case 8:printf("\nThere is Save(), which is been realized!\n");

                            Save(T);getchar();

                            break;

                     case 9:printf("\nThere is Open(), which is been realized!\n");

                            Open(&T);getchar();

                            break;

                     default: ;

        }//switch

    }while(op);

    printf("welcome to the system again!");

    return 0;

}

Status menu(void){

       printf("\t\t\tmenu for BiTree\n");

       printf("--------------------------------------------------------\n");

       printf("\t 1.CreatBiTree\n");

       printf("\t 2.PreOrderTraverse \t 3.InOrderTraverse\n");

       printf("\t 4.PostOrderTraverse\t 5.LevelOrderTraverse\n");

       printf("\t 6.BiTreeLeaf       \t 7.BiTreeDepth\n");

       printf("\t 8.Save             \t 9.Open\n");

       printf("\t 0.Exit\n");

       printf("--------------------------------------------------------\n");

    return 0;

}//menu

Status DisplayInput(char *s,int num){

       int i=0;

       printf("--------------------------------------------------------\n");

       printf("The Input: ");

       while(i<num){

              if(*(s+i)!=' ')

                     printf("%c",*(s+i));

              else

                     printf("%c",BiTreeSpInput);

              i++;

       }

       putchar('\n');

       return 0;

}//DisplayInput

Status DisplayOutput(BiTNode *T){

       //按顺序分别显示各操作的结果

       if(T){

              printf("--------------------------------------------------------");

              PreOrderTraverse(T,Visit);

              InOrderTraverse(T,Visit);

              PostOrderTraverse(T,Visit);

              LevelOrderTraverse(T,Visit);

              BiTreeLeaf(T);

              printf("\nThe depth of the BiTree is %d",BiTreeDepth(T));

              printf("\n--------------------------------------------------------\n");

       }

       return 0;

}//DisplayOutput

Status CreatBiTree(BiTNode ** T,char *s,int *num){

       //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,

       //构造二叉链表表示的二叉树T。

       char ch;

       printf("\nPlease input the BiTree(PreOrder): ");

       scanf("%c",&ch);

       *(s+(*num)++)=ch;

       if(ch=='\n') (*T)=NULL;

       else{

              if(ch==' ')(*T)=NULL;

              else{

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

                            printf("节点空间分配失败!\n");

                            exit(ERROR);

                            }

                     (*T)->elem.data=ch;

                     CreatBiTree(&(*T)->lchild,s,num);

                     CreatBiTree(&(*T)->rchild,s,num);

              }

       }

       return 0;

}//CreatBiTree

Status PreOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e)){

       //先输出,再入栈,

       //访问左子树

       //出栈,访问右子树

       SqStack s;

       InitStack(&s);

       if(!T)

              printf("This is an ampty BiTree!\n");

       else{

              printf("\nthe PreOrder:\t");

              while(T!=NULL||s.top!=s.base){

                     if(T!=NULL){

                            printf("%c",T->elem.data);

                            putchar(' ');

                            Push(&s,T);

                            T=T->lchild;

                     }

                     else {

                            Pop(&s,&T);

                            T=T->rchild;

                     }

              }//while

       }

       return 0;

}//PreOrderTraverse

Status InOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e)){

       //先入栈,访问左子树

       //出栈,输出

       //访问右子树

       SqStack s;

       InitStack(&s);

       if(!T)

              printf("This is an ampty BiTree!\n");

       else{

              printf("\nthe InOrder:\t");

              while(T!=NULL||s.top!=s.base){

                     if(T!=NULL){

                            Push(&s,T);

                            T=T->lchild;

                     }

                     else{

                            Pop(&s,&T);

                            printf("%c",T->elem.data);

                            putchar(' ');

                            T=T->rchild;

                     }

              }//while

       }

       return 0;

}//InOrderTraverse

Status PostOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e)){

       //用两个栈,访问左子树,入栈s1,访问右子树,入栈s2,当栈顶s1=s2时,表明

       //栈顶元素的左右子树都被访问,此时 出栈,输出

       SqStack s1,s2;

       InitStack(&s1);

       InitStack(&s2);

       if(!T)

              printf("This is an ampty BiTree!\n");

       else{

              printf("\nthe PostOrder:\t");

              while(T!=NULL|| s1.top!=s1.base){

                     if(T!=NULL){

                            Push(&s1,T);

                            T=T->lchild;

                     }

                     else{

                            if(s2.top!=s2.base&&*(s1.top-1)==*(s2.top-1)){

                                   Pop(&s1,&T);

                                   s2.top--;

                                   printf("%c",T->elem.data);

                                   putchar(' ');

                                   T=NULL;

                            }

                            else{

                                   Pop(&s1,&T);

                                   Push(&s1,T);

                                   Push(&s2,T);

                                   T=T->rchild;

                            }

                     }

              }//while

       }

       return 0;

}//PostOrderTraverse

Status BiTreeLeaf(BiTNode * T){

       //参照层次遍历,

       //出队,判断左右孩子是否为空,是则输出,计数加1;否则将左右孩子入队

       SqQueue q;

       int leaf=0;

       InitQueue(&q);

       if(!T){

              printf("This is an ampty BiTree!\n");

              return 0;

       }

       printf("\nThe leaf(leaves) is(are): ");

       if(T!=NULL) En(&q,T);

       while(q.front!=q.rear){

              De(&q,&T);

              if(T->lchild==NULL&&T->rchild==NULL){

                     printf("%c",T->elem.data);

                     putchar(' ');

                     leaf++;

              }

              else{

                     if(T->lchild)En(&q,T->lchild);

                     if(T->rchild)En(&q,T->rchild);

              }

       }

       printf("\nThe number(s) of leaf(leaves) is %d",leaf);

       return leaf;

}//BiTreeLeaf

Status LevelOrderTraverse(BiTNode * T,Status(*Visit)(TElemType e)){

       //将根结点指针入队

       //出队,输出,将左右孩子指针入队

       SqQueue q;

       InitQueue(&q);

       if(!T){

              printf("This is an ampty BiTree!\n");

              return 0;

       }

       else{

              printf("\nThe LevelOrder:\t");

              En(&q,T);

              while(q.front!=q.rear){

                     De(&q,&T);

                     printf("%c",T->elem.data);

                     putchar(' ');

                     if(T->lchild)En(&q,T->lchild);

                     if(T->rchild)En(&q,T->rchild);

              }

       }

       return 0;

}//LevelOrderTraverse

Status BiTreeDepth(BiTNode * T){

       //递归,树的深度等于左右子树深度的较大值加1

       int depth,depthleft,depthright;

       if(!T)depth=0;

       else {

              depthleft=BiTreeDepth(T->lchild);

              depthright=BiTreeDepth(T->rchild);

              depth=1+(depthleft>depthright?depthleft:depthright);

       }

       return depth;

}//BiTreeDepth

Status Visit(TElemType e){

       printf("%c",e.data);

       putchar(' ');

       return 0;

}//Visit

Status InitStack(SqStack *s){

       s->base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));

       if(!s->base) exit(ERROR);

       s->top=s->base;

       s->stacksize=STACK_INIT_SIZE;

       return 0;

}//InitStack

Status Push(SqStack *s,SElemType e){

       if(s->top-s->base>=s->stacksize){

              s->base=(SElemType *)realloc(s->base,(s->stacksize+STACKINCREMENT) * sizeof(SElemType));

              if(!s->base) exit(ERROR);

              s->top=s->base+s->stacksize;

              s->stacksize+=STACKINCREMENT;

       }

       *s->top++=e;

       return 0;

}//Push

Status Pop(SqStack *s,SElemType* e){

       if(s->top==s->base) return ERROR;

       (*e)=*--s->top; //s->top--;e=*s->top;

       return 0;

}//Pop

Status InitQueue(SqQueue *q){

       q->base=(QElemType *)malloc(MAXQSIZE *sizeof(QElemType));

       if(!q->base) exit(ERROR);

       q->front=q->rear=0;

       return 0;

}//InitQueue

Status En(SqQueue *q,QElemType e){

       if((q->rear+1)%MAXQSIZE==q->front) return ERROR;

       q->base[q->rear]=e;

       q->rear=(q->rear+1)%MAXQSIZE;

       return 0;

}//En

Status De(SqQueue *q,QElemType *e){

       if(q->front==q->rear) return ERROR;

       (*e)=q->base[q->front];

       q->front=(q->front+1)%MAXQSIZE;

       return 0;

}//De

Status Save(BiTNode *T){

       FILE *fin=fopen("c:\\BiTree.txt","w+");

       SqStack s;

       InitStack(&s);

       while(T!=NULL||s.top!=s.base){

              if(T!=NULL){

                     fprintf(fin,"%c",T->elem.data);

                     Push(&s,T);

                     T=T->lchild;

              }

              else {

                     fprintf(fin,"%c",BiTreeSp);

                     Pop(&s,&T);

                     T=T->rchild;

              }

       }//while

       if(T==NULL&&s.top==s.base)

              fprintf(fin,"%c",BiTreeSp);

       fclose(fin);

       printf("\nSaved!\n");

       return 0;

}//Save

Status Open(BiTNode **T){

       FILE *fout;

       char s[MAX];

       int i=0;

       fout=fopen("c:\\BiTree.txt","r+");

       if(!fout){

              printf("The file is not exist!\n");

              return 0;

       }

       fscanf(fout,"%s",s);

       WriteBiTree(T,s,&i);

       printf("\nOpened!\n");

       return 0;

}//Open

Status WriteBiTree(BiTNode **T,char *s,int *i){

       char ch;

       ch=s[*i];(*i)++;

       if(ch=='\0'){

       //     (*T)=NULL;

              return 0;

       }

       if(ch==BiTreeSp)

              (*T)=NULL;

       else{

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

                     printf("节点空间分配失败!\n");

                     exit(ERROR);

                     }

              (*T)->elem.data=ch;

              WriteBiTree(&(*T)->lchild,s,i);

              WriteBiTree(&(*T)->rchild,s,i);

       }

       return 0;

}

4.4 效率分析

遍历二叉树的算法中的基本操作是访问结点,则不论按哪种次序进行遍历,对含n个结点的二叉树,其时间复杂度均为O(n)。所需辅助空间为遍历过程中栈的最大容量即树深,最坏情况为n则空间复杂度也为O(n)。 

求树深和叶子数目是基于遍历实现的时间和空间复杂度也均为O(n)。


5 实验总结与评价

   通过此次上机实验,我对线性表,链表及二叉树有了更加深刻的认识。对于线性表和链表的几种基本操作有了更加熟练的掌握,对于二叉树的几种遍历过程也有了更为深刻的理解。在实验过程中,由于链式存储不具备随机存取的特点,导致在变成过程中遇到了一些困难,而对于二叉树,主要是通过遍历来对结点进行各种操作。总的来说,实验过程锻炼了自己的动手能力,也让我体会到了细致认真的重要性。

更多相关推荐:
数据结构实验报告

实验报告实验课程:数据结构实验项目:实验专业:计算机科学与技术姓名:**学号:***指导教师:**实验时间:20**-12-7重庆工学院计算机学院数据结构实验报告实验一线性表1.实验要求掌握数据结构中线性表的基…

数据结构实验报告(C语言)(强力推荐)

数据结构实验实验内容和目的掌握几种基本的数据结构集合线性结构树形结构等在求解实际问题中的应用以及培养书写规范文档的技巧学习基本的查找和排序技术让我们在实际上机中具有编制相当规模的程序的能力养成一种良好的程序设计...

数据结构实验———图实验报告

数据结构实验报告目的要求掌握图的存储思想及其存储实现掌握图的深度广度优先遍历算法思想及其程序实现掌握图的常见应用算法的思想及其程序实现实验内容键盘输入数据建立一个有向图的邻接表输出该邻接表3在有向图的邻接表的基...

数据结构实验报告格式

数据结构实验报告格式实验11顺序表的基本操作一实验目的1掌握使用VC上机调试线性表的基本方法2掌握线性表的基本操作插入删除查找等运算在顺序存储结构上的实现二实验内容顺序表的基本操作的实现三实验要求1认真阅读和理...

数据结构实验报告全集

数据结构实验报告全集实验一线性表基本操作和简单程序1实验目的1掌握使用VisualC60上机调试程序的基本方法2掌握线性表的基本操作初始化插入删除取数据元素等运算在顺序存储结构和链表存储结构上的程序设计方法2实...

数据结构实验报告5

计算机科学与工程系计算机科学与工程系2计算机科学与工程系附录可包括源程序清单或其它说明includeltiostreamgtincludeltstdiohgtusingnamespacestdtypedefst...

数据结构实验报告[4]

云南大学数据结构实验报告第四次实验学号姓名一实验目的复习线性表的逻辑结构存储结构及基本操作掌握顺序表和带头结点单链表了解有序表二实验内容必做题假设有序表中数据元素类型是整型请采用顺序表或带头结点单链表实现Ord...

数据结构树的实验报告

数据结构实验报告目的要求1掌握二叉树的存储实现2掌握二叉树的遍历思想3掌握二叉树的常见算法的程序实现实验内容1输入字符序列建立二叉链表2中序遍历二叉树递归算法3中序遍历二叉树非递归算法最好也能实现先序后序非递归...

数据结构实验报告

武汉大学国际软件学院实验报告课程名称专业年级姓名学号协作者实验学期课堂时数填写时间月6小结对本次实验的心得体会所遇到的问题及解决方法其他思考和建议7指导教师评语及成绩指导教师依据学生的实际报告内容用简练语言给出...

数据结构第一次上机实验报告

数据结构第一次上机实验报告线性表实验要求1实现顺序表结构的创建插入删除查找等操作2利用上述顺序表操作实现如下程序建立两个顺序表表示的集合集合中无重复的元素并求这样的两个集合的并交和源程序C实现visualstu...

数据结构实验报告(重邮)5个

学号数据结构实验报告学院班级姓名实验一线性链表的实现与操作题目设计一个100位以内的长整数加减运算的程序班级姓名学号完成日期一需求分析1本实验中100位长整数的每位上的数字必须为数字09之间长整数的位数并要求1...

安徽工业大学数据结构实验报告

安徽工业大学计算机学院数据结构实验报告姓名学号班级教师内容线性表基本操作的实现栈的基本操作串的模式匹配二叉树操作图的创建与遍历20xx525实验一线性表基本操作的实现一实验目的1掌握使用TurboC20上机调试...

数据结构实验报告(46篇)