数据结构期末考试复习资料(函数题)

 

 

6-2 顺序表基本操作 (10 分)

本题要求实现顺序表元素的增、删、查找以及顺序表输出共4个基本操作函数。L是一个顺序表,函数Status ListInsert_Sq(SqList &L, int pos, ElemType e)是在顺序表的pos位置插入一个元素e(pos应该从1开始),函数Status ListDelete_Sq(SqList &L, int pos, ElemType &e)是删除顺序表的pos位置的元素并用引用型参数e带回(pos应该从1开始),函数int ListLocate_Sq(SqList L, ElemType e)是查询元素e在顺序表的位次并返回(如有多个取第一个位置,返回的是位次,从1开始,不存在则返回0),函数void ListPrint_Sq(SqList L)是输出顺序表元素。实现时需考虑表满扩容的问题。

函数接口定义:

Status ListInsert_Sq(SqList &L, int pos, ElemType e);
Status ListDelete_Sq(SqList &L, int pos, ElemType &e);
int ListLocate_Sq(SqList L, ElemType e);
void ListPrint_Sq(SqList L);

其中 L 是顺序表。 pos 是位置; e 代表元素。当插入与删除操作中的pos参数非法时,函数返回ERROR,否则返回OK。

裁判测试程序样例:


//库函数头文件包含
#include
#include
#include


//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;

//顺序表的存储结构定义
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10
typedef int ElemType;  //假设线性表中的元素均为整型
typedef struct{
    ElemType* elem;   //存储空间基地址
    int length;       //表中元素的个数
    int listsize;     //表容量大小
}SqList;    //顺序表类型定义
Status ListInsert_Sq(SqList &L, int pos, ElemType e);
Status ListDelete_Sq(SqList &L, int pos, ElemType &e);
int ListLocate_Sq(SqList L, ElemType e);
void ListPrint_Sq(SqList L);

//结构初始化与销毁操作
Status InitList_Sq(SqList &L){
  //初始化L为一个空的有序顺序表
    L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(!L.elem)exit(OVERFLOW);
    L.listsize=LIST_INIT_SIZE;
    L.length=0;
    return OK;
}


int main() {
    SqList L;

    if(InitList_Sq(L)!= OK) {
        printf("InitList_Sq: 初始化失败!!!\n");
        return -1;
    }

    for(int i = 1; i <= 10; ++ i)
        ListInsert_Sq(L, i, i);

    int operationNumber;  //操作次数
    scanf("%d", &operationNumber);

    while(operationNumber != 0) {
        int operationType;  //操作种类
        scanf("%d", & operationType);

        if(operationType == 1) {  //增加操作
            int pos, elem;
            scanf("%d%d", &pos, &elem);
            ListInsert_Sq(L, pos, elem);
        } else if(operationType == 2) {  //删除操作
             int pos; ElemType elem;
             scanf("%d", &pos);
             ListDelete_Sq(L, pos, elem);
             printf("%d\n", elem);
        } else if(operationType == 3) {  //查找定位操作
            ElemType elem;
            scanf("%d", &elem);
            int pos = ListLocate_Sq(L, elem);
            if(pos >= 1 && pos <= L.length)
                printf("%d\n", pos);
            else
                printf("NOT FIND!\n");
        } else if(operationType == 4) {  //输出操作
            ListPrint_Sq(L);
        }
       operationNumber--;
    }
    return 0;
}

/* 请在这里填写答案 */

输入格式: 第一行输入一个整数operationNumber,表示操作数,接下来operationNumber行,每行表示一个操作信息(含“操作种类编号 操作内容”)。 编号为1表示插入操作,后面两个参数表示插入的位置和插入的元素值 编号为2表示删除操作,后面一个参数表示删除的位置 编号为3表示查找操作,后面一个参数表示查找的值 编号为4表示顺序表输出操作 输出格式: 对于操作2,输出删除的元素的值 对于操作3,输出该元素的位置,如果不存在该元素,输出“NOT FOUND”; 对于操作4,顺序输出整个顺序表的元素,两个元素之间用空格隔开,最后一个元素后面没有空格。

输入样例:

4
1 1 11
2 2
3 3
4

输出样例:

1
3
11 2 3 4 5 6 7 8 9 10
#include
#include
#include


//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;

//顺序表的存储结构定义
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10
typedef int ElemType;  //假设线性表中的元素均为整型
typedef struct{
    ElemType* elem;   //存储空间基地址
    int length;       //表中元素的个数
    int listsize;     //表容量大小
}SqList;    //顺序表类型定义
Status ListInsert_Sq(SqList &L, int pos, ElemType e);
Status ListDelete_Sq(SqList &L, int pos, ElemType &e);
int ListLocate_Sq(SqList L, ElemType e);
void ListPrint_Sq(SqList L);

//结构初始化与销毁操作
Status InitList_Sq(SqList &L){
  //初始化L为一个空的有序顺序表
    L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(!L.elem)exit(OVERFLOW);
    L.listsize=LIST_INIT_SIZE;
    L.length=0;
    return OK;
}


int main() {
    SqList L;

    if(InitList_Sq(L)!= OK) {
        printf("InitList_Sq: 初始化失败!!!\n");
        return -1;
    }

    for(int i = 1; i <= 10; ++ i)
        ListInsert_Sq(L, i, i);
    ListPrint_Sq(L);

    int operationNumber;  //操作次数
    scanf("%d", &operationNumber);

    while(operationNumber != 0) {
        int operationType;  //操作种类
        scanf("%d", & operationType);

        if(operationType == 1) {  //增加操作
            int pos, elem;
            scanf("%d%d", &pos, &elem);
            ListInsert_Sq(L, pos, elem);
            ListPrint_Sq(L);

        } else if(operationType == 2) {  //删除操作
             int pos; ElemType elem;
             scanf("%d", &pos);
             ListDelete_Sq(L, pos, elem);
             printf("%d\n", elem);
             ListPrint_Sq(L);
        } else if(operationType == 3) {  //查找定位操作
            ElemType elem;
            scanf("%d", &elem);
            int pos = ListLocate_Sq(L, elem);
            if(pos >= 1 && pos <= L.length)
                printf("%d\n", pos);
            else
                printf("NOT FIND!\n");
        } else if(operationType == 4) {  //输出操作
            ListPrint_Sq(L);
        }
       operationNumber--;
    }
    return 0;
}

Status ListInsert_Sq(SqList &L, int pos, ElemType e)
{
    if(pos<1||pos>L.length+1) return -1;
    pos=pos-1;

    ElemType *t=(ElemType*)malloc((L.length+10)*sizeof(ElemType));
    for(int i=0;i=L.listsize)
    {
         L.elem=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
         L.listsize+=10;
    }

    for(int i=0;iL.length) return -1;
    pos=pos-1;

    ElemType *t=(ElemType*)malloc((L.length+10)*sizeof(ElemType));
    for(int i=0;i

6-1 循环单链表区间删除 (15 分)

本题要求实现带头结点的循环单链表的创建和单链表的区间删除。L是一个带头结点的循环单链表,函数ListCreate_CL用于创建一个循环单链表,函数ListDelete_CL用于删除取值大于min小于max的链表元素。

函数接口定义:

    Status ListCreate_CL(LinkList &CL); 
    void ListDelete_CL(LinkList &CL,ElemType min,ElemType max);

裁判测试程序样例:

//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型  

typedef struct LNode
{  
    ElemType data;  
    struct LNode *next; 
}LNode,*LinkList; //循环单链表类型定义与单链表定义相同,区别在尾节点next取值

Status ListCreate_CL(LinkList &CL);  

void ListDelete_CL(LinkList &CL, ElemType min, ElemType max);

void ListPrint_CL(LinkList &CL) 
{   //输出单链表,空表时输出Empty List。 
    LNode *p=CL->next;  //p指向第一个元素结点
    if(p==CL){
      printf("Empty List");
      return;
    }
    while(p!=CL)  
    {   
        if(p->next!=CL)
            printf("%d ",p->data);   
        else
            printf("%d",p->data);      
        p=p->next; 
    } 
}    
int main() 
{  
    LinkList CL;
    ElemType min,max;
    if(ListCreate_CL(CL)!= OK) 
    {
       printf("循环链表创建失败!!!\n");
       return -1;
    }
    scanf("%d%d",&min,&max);    
    ListDelete_CL(CL,min,max);   
    ListPrint_CL(CL);  	
    return 0;
}

/* 请在这里填写答案 */

输入格式: 第一行输入一个整数n,表示循环单链表中元素个数,接下来一行共n个整数,中间用空格隔开。第三行输入min和max。

输出格式: 输出删除后循环链表的各个元素,两个元素之间用空格隔开,最后一个元素后面没有空格。

输入样例:

6
1 2 3 4 5 6
2 5

输出样例:

1 2 5 6
//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList; //循环单链表类型定义与单链表定义相同,区别在尾节点next取值

Status ListCreate_CL(LinkList &CL);

void ListDelete_CL(LinkList &CL, ElemType min, ElemType max);

void ListPrint_CL(LinkList &CL)
{   //输出单链表,空表时输出Empty List。
    LNode *p=CL->next;  //p指向第一个元素结点
    if(p==CL){
      printf("Empty List");
      return;
    }

    while(p!=CL)
    {
        if(p->next!=CL)
            printf("%d ",p->data);
        else
            printf("%d",p->data);
        p=p->next;
    }
}
int main()
{
    LinkList CL;
    ElemType min,max;
    if(ListCreate_CL(CL)!= OK)
    {
       printf("循环链表创建失败!!!\n");
       return -1;
    }
    scanf("%d%d",&min,&max);
    ListDelete_CL(CL,min,max);
    ListPrint_CL(CL);
    return 0;
}

Status ListCreate_CL(LinkList &CL)
{
    CL=(LNode *)malloc(sizeof(LNode));

    LNode* p=CL,*t;
    int n; scanf("%d",&n);
    for(int i=0;inext=(LNode *)malloc(sizeof(LNode));
        scanf("%d",&p->next->data);
        p=p->next;
    }
    p->next=CL;
    return 1;
}

void ListDelete_CL(LinkList &CL, ElemType min, ElemType max)
{
    LNode *p=CL->next,*q=CL;
    while(p!=CL)
    {
        if(p->data>min&&p->datanext=p->next;
        }
        else
        {
            q=p;
        }

        p=p->next;
    }
}

//注意结点的创立,并不止这一种方法,但是这种最普遍。
//注意循环链表的特点,在创建链表的时候有一步p->next=CL的操作。
//注意进行删除时对q的更新,否则会造成死循环。

 

 

6-35 单链表元素定位 (12 分)

本题要求在链表中查找第一个数据域取值为x的节点,返回节点的位序。L是一个带头结点的单链表,函数ListLocate_L(LinkList L, ElemType x)要求在链表中查找第一个数据域取值为x的节点,返回其位序(从1开始),查找不到则返回0。例如,原单链表各个元素节点的元素依次为1,2,3,4,则ListLocate_L(L, 1)返回1,ListLocate_L(L, 3)返回3,而ListLocate_L(L, 100)返回0。

函数接口定义:

int ListLocate_L(LinkList L, ElemType x);

其中 L 是一个带头节点的单链表。 x 是一个给定的值。函数须在链表中查找第一个数据域取值为x的节点。若找到则返回其位序(从1开始),找不到则返回0。

裁判测试程序样例:


//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L(LinkList &L,int n)
{
    LNode *rearPtr,*curPtr;   //一个尾指针,一个指向新节点的指针
    L=(LNode*)malloc(sizeof (LNode));
    if(!L)exit(OVERFLOW);
    L->next=NULL;               //先建立一个带头结点的单链表
    rearPtr=L;  //初始时头结点为尾节点,rearPtr指向尾巴节点
    for (int i=1;i<=n;i++){  //每次循环都开辟一个新节点,并把新节点拼到尾节点后
        curPtr=(LNode*)malloc(sizeof(LNode));//生成新结点
        if(!curPtr)exit(OVERFLOW);
        scanf("%d",&curPtr->data);//输入元素值
        curPtr->next=NULL;  //最后一个节点的next赋空
        rearPtr->next=curPtr;
        rearPtr=curPtr;
    }
    return OK;
}
//下面是需要实现的函数的声明
int ListLocate_L(LinkList L, ElemType x);

int main()
{
    LinkList L;
    int n;
    int x,k;   
    scanf("%d",&n);  //输入链表中元素个数
    if(ListCreate_L(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
   scanf("%d",&x); //输入待查找元素
   k=ListLocate_L(L,x);
   printf("%d\n",k);
   return 0;
}

/* 请在这里填写答案 */

输入样例:

4
1 2 3 4
1

输出样例:

1
//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L(LinkList &L,int n)
{
    LNode *rearPtr,*curPtr;   //一个尾指针,一个指向新节点的指针
    L=(LNode*)malloc(sizeof (LNode));
    if(!L)exit(OVERFLOW);
    L->next=NULL;               //先建立一个带头结点的单链表
    rearPtr=L;  //初始时头结点为尾节点,rearPtr指向尾巴节点
    for (int i=1;i<=n;i++){  //每次循环都开辟一个新节点,并把新节点拼到尾节点后
        curPtr=(LNode*)malloc(sizeof(LNode));//生成新结点
        if(!curPtr)exit(OVERFLOW);
        scanf("%d",&curPtr->data);//输入元素值
        curPtr->next=NULL;  //最后一个节点的next赋空
        rearPtr->next=curPtr;
        rearPtr=curPtr;
    }
    return OK;
}
//下面是需要实现的函数的声明
int ListLocate_L(LinkList L, ElemType x);

int main()
{
    LinkList L;
    int n;
    int x,k;   
    scanf("%d",&n);  //输入链表中元素个数
    if(ListCreate_L(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
   scanf("%d",&x); //输入待查找元素
   k=ListLocate_L(L,x);
   printf("%d\n",k);
   return 0;
}

int ListLocate_L(LinkList L, ElemType x)
{
    LNode* p=L->next;
    int pos=0;
    while(p!=NULL)
    {
        pos++;
        if(p->data==x) return pos;
        p=p->next;
    }
    return 0;
}

 

 

6-72 顺序表创建和就地逆置 (10 分)

本题要求实现顺序表的创建和就地逆置操作函数。L是一个顺序表,函数ListCreate_Sq(SqList &L)用于创建一个顺序表,函数ListReverse_Sq(SqList &L)是在不引入辅助数组的前提下将顺序表中的元素进行逆置,如原顺序表元素依次为1,2,3,4,则逆置后为4,3,2,1。

函数接口定义:

Status ListCreate_Sq(SqList &L);
void ListReverse_Sq(SqList &L);

裁判测试程序样例:

//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;

//顺序表的存储结构定义
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10
typedef int ElemType;  //假设线性表中的元素均为整型
typedef struct{
    ElemType* elem;   //存储空间基地址
    int length;       //表中元素的个数
    int listsize;     //表容量大小
}SqList;    //顺序表类型定义

Status ListCreate_Sq(SqList &L);
void ListReverse_Sq(SqList &L);

int main() {
    SqList L;
    ElemType *p;

    if(ListCreate_Sq(L)!= OK) {
        printf("ListCreate_Sq: 创建失败!!!\n");
        return -1;
    }

    ListReverse_Sq(L);

    if(L.length){
	for(p=L.elem;p

输入格式: 第一行输入一个整数n,表示顺序表中元素个数,接下来n个整数为表元素,中间用空格隔开。 输出格式: 输出逆置后顺序表的各个元素,两个元素之间用空格隔开,最后一个元素后面没有空格。

输入样例:

4
1 2 3 4

输出样例:

4 3 2 1
//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;

//顺序表的存储结构定义
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10
typedef int ElemType;  //假设线性表中的元素均为整型
typedef struct{
    ElemType* elem;   //存储空间基地址
    int length;       //表中元素的个数
    int listsize;     //表容量大小
}SqList;    //顺序表类型定义

Status ListCreate_Sq(SqList &L);
void ListReverse_Sq(SqList &L);

int main() {
    SqList L;
    ElemType *p;

    if(ListCreate_Sq(L)!= OK) {
        printf("ListCreate_Sq: 创建失败!!!\n");
        return -1;
    }

    ListReverse_Sq(L);

    if(L.length){
	for(p=L.elem;p

 

6-73 有序顺序表的插入 (10 分)

本题要求实现递增顺序表的有序插入函数。L是一个递增的有序顺序表,函数Status ListInsert_SortedSq(SqList &L, ElemType e)用于向顺序表中按递增的顺序插入一个数据。 比如:原数据有:2 5,要插入一个元素3,那么插入后顺序表为2 3 5。 要考虑扩容的问题。

函数接口定义:

Status ListInsert_SortedSq(SqList &L, ElemType e);

裁判测试程序样例:

//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;

//顺序表的存储结构定义
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10
typedef int ElemType;  //假设线性表中的元素均为整型
typedef struct{
    ElemType* elem;   //存储空间基地址
    int length;       //表中元素的个数
    int listsize;     //表容量大小
}SqList;    //顺序表类型定义

//函数声明
Status ListInsert_SortedSq(SqList &L, ElemType e);

//顺序表初始化函数
Status InitList_Sq(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;
}

//顺序表输出函数
void ListPrint_Sq(SqList L)
{
    ElemType *p = L.elem;//遍历元素用的指针

	
    for(int i = 0; i < L.length; ++i){
        if(i == L.length - 1){
            printf("%d", *(p+i));
        }
        else{
            printf("%d ", *(p+i));
        }
    }
}
int main()
{
    //声明一个顺序表
    SqList L;
    //初始化顺序表
    InitList_Sq(L);

    int number = 0;
    ElemType e;

     scanf("%d", &number);//插入数据的个数 

    for(int i = 0; i < number; ++i)
    {
	scanf("%d", &e);//输入数据
        ListInsert_SortedSq(L, e);
    }

    ListPrint_Sq(L);

    return  0;
}


/* 请在这里填写答案 */

输入格式: 第一行输入接下来要插入的数字的个数 第二行输入数字 输出格式: 输出插入之后的数字

输入样例:

5
2 3 9 8 4

输出样例:

2 3 4 8 9
//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;

//顺序表的存储结构定义
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10
typedef int ElemType;  //假设线性表中的元素均为整型
typedef struct{
    ElemType* elem;   //存储空间基地址
    int length;       //表中元素的个数
    int listsize;     //表容量大小
}SqList;    //顺序表类型定义

//函数声明
Status ListInsert_SortedSq(SqList &L, ElemType e);

//顺序表初始化函数
Status InitList_Sq(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;
}

//顺序表输出函数
void ListPrint_Sq(SqList L)
{
    ElemType *p = L.elem;//遍历元素用的指针


    for(int i = 0; i < L.length; ++i){
        if(i == L.length - 1){
            printf("%d", *(p+i));
        }
        else{
            printf("%d ", *(p+i));
        }
    }
    printf("\n");
}
int main()
{
    //声明一个顺序表
    SqList L;
    //初始化顺序表
    InitList_Sq(L);

    int number = 0;
    ElemType e;

     scanf("%d", &number);//插入数据的个数

    for(int i = 0; i < number; ++i)
    {
	scanf("%d", &e);//输入数据
        ListInsert_SortedSq(L, e);
        ListPrint_Sq(L);
    }

    ListPrint_Sq(L);

    return  0;
}

Status ListInsert_SortedSq(SqList &L, ElemType e)
{
    if(L.length>=L.listsize)
    {
        L.elem=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
        L.listsize+=LISTINCREMENT;
    }

    int *t=(ElemType *)malloc(L.listsize*sizeof(ElemType));
    int pos=0;
    for(int i=0;ie)
        {
            break;
        }
        t[i]=L.elem[i];
        pos++;
    }

    t[pos]=e;
    for(int i=pos;i

 

 下面这个一定要重点注意下

6-89 带头结点的单链表就地逆置 (10 分)

本题要求编写函数实现带头结点的单链线性表的就地逆置操作函数。L是一个带头结点的单链表,函数ListReverse_L(LinkList &L)要求在不新开辟节点的前提下将单链表中的元素进行逆置,如原单链表元素依次为1,2,3,4,则逆置后为4,3,2,1。

函数接口定义:

void ListReverse_L(LinkList &L);

其中 L 是一个带头结点的单链表。

裁判测试程序样例:

//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L(LinkList &L,int n)
{
    LNode *rearPtr,*curPtr;   //一个尾指针,一个指向新节点的指针
    L=(LNode*)malloc(sizeof (LNode));
    if(!L)exit(OVERFLOW);
    L->next=NULL;               //先建立一个带头结点的单链表
    rearPtr=L;  //初始时头结点为尾节点,rearPtr指向尾巴节点
    for (int i=1;i<=n;i++){  //每次循环都开辟一个新节点,并把新节点拼到尾节点后
        curPtr=(LNode*)malloc(sizeof(LNode));//生成新结点
        if(!curPtr)exit(OVERFLOW);
        scanf("%d",&curPtr->data);//输入元素值
        curPtr->next=NULL;  //最后一个节点的next赋空
        rearPtr->next=curPtr;
        rearPtr=curPtr;
    }
    return OK;
}
void ListReverse_L(LinkList &L);
void ListPrint_L(LinkList &L){
//输出单链表
    LNode *p=L->next;  //p指向第一个元素结点
    while(p!=NULL)
    {
          if(p->next!=NULL)
               printf("%d ",p->data);
          else
               printf("%d",p->data);
          p=p->next;
    }
}
int main()
{
    LinkList L;
    int n;
    scanf("%d",&n);
    if(ListCreate_L(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
    ListReverse_L(L);
    ListPrint_L(L);
    return 0;
}
/* 请在这里填写答案 */

输入格式

第一行输入一个整数n,表示单链表中元素个数,接下来一行共n个整数,中间用空格隔开。

输出格式

输出逆置后顺序表的各个元素,两个元素之间用空格隔开,最后一个元素后面没有空格。

输入样例:

4
1 2 3 4

输出样例:

4 3 2 1
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L(LinkList &L,int n)
{
    LNode *rearPtr,*curPtr;   //一个尾指针,一个指向新节点的指针
    L=(LNode*)malloc(sizeof (LNode));
    if(!L)exit(OVERFLOW);
    L->next=NULL;               //先建立一个带头结点的单链表
    rearPtr=L;  //初始时头结点为尾节点,rearPtr指向尾巴节点
    for (int i=1;i<=n;i++){  //每次循环都开辟一个新节点,并把新节点拼到尾节点后
        curPtr=(LNode*)malloc(sizeof(LNode));//生成新结点
        if(!curPtr)exit(OVERFLOW);
        scanf("%d",&curPtr->data);//输入元素值
        curPtr->next=NULL;  //最后一个节点的next赋空
        rearPtr->next=curPtr;
        rearPtr=curPtr;
    }
    return OK;
}
void ListReverse_L(LinkList &L);
void ListPrint_L(LinkList &L){
//输出单链表
    LNode *p=L->next;  //p指向第一个元素结点
    while(p!=NULL)
    {
          if(p->next!=NULL)
               printf("%d ",p->data);
          else
               printf("%d",p->data);
          p=p->next;
    }
}
int main()
{
    LinkList L;
    int n;
    scanf("%d",&n);
    if(ListCreate_L(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
    ListReverse_L(L);
    ListPrint_L(L);
    return 0;
}
/* 请在这里填写答案 */

void ListReverse_L(LinkList &L)
{
    if(L==NULL||L->next==NULL||L->next->next==NULL) return ;

    LNode *p=L->next->next;
    L->next->next=NULL;

    while(p)
    {
        LNode *q=p->next;
        p->next=L->next;
        L->next=p;
        p=q;
    }

}
//注意其中所蕴含的逻辑,建议自己画图模拟,每次都只弄一个点,每次都把一个放到一个的前面。

 

//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L_Rec(LinkList &L,int n)
{
//递归边界:创建空表时只需将L赋空即可;
//递归关系:创建非空表时,将链表看做两部分:首元素组成的子表La, 第二个元素及其后元素构成的子表Lb。
//子表La容易创建(只需开辟一个节点)
//子表Lb由于规模小可以递归创建完成(类似数学归纳法的假设,只要小的都可以建设能完成)
//最后将两个子表拼接即可。
  LNode *La, *Lb;
  if(n==0) L=NULL;
  else{
    La=(LNode *)malloc(sizeof(LNode));  //开辟子表La
    if(!La) exit(OVERFLOW);
    scanf("%d",&La->data);
    ListCreate_L_Rec(Lb,n-1 ); //递归创建子表Lb
    La->next = Lb;  //两个子表拼结
    L=La;  //第一个子表的地址赋给L。请思考为什这样处理不会使得主函数中的L取错值?
  }
  return OK;
}
void ListPrint_L_Rec(LinkList L);

int main()
{
    LinkList L;
    int n;
    scanf("%d",&n);
    if(ListCreate_L_Rec(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
    ListPrint_L_Rec (L);
    return 0;
}
/* 请在这里填写答案 */

输入格式

第一行输入一个整数n,表示单链表中元素个数,接下来一行共n个整数,中间用空格隔开。

输出格式

递归输出链表的各个元素,每个元素前都有一个用空格,首元素元素前面也有空格。

输入样例:

4
1 2 3 4

输出样例:

1 2 3 4

6-136 递归程序设计方法练习--递归输出单链表 (10 分)

本题要求用递归方法编写递归函数实现无头结点单链表的输出操作函数。L是一个不带头结点的单链表,函数void ListPrint_L_Rec(LinkList L)要求用递归的方法输出无头结点之单链表中各个元素的值,每个元素的前面都有一个空格(包括首元素)。递归思想可借鉴下述代码中链表创建的递归函数。

函数接口定义:

void ListPrint_L_Rec(LinkList L);

其中 L 是一个不带头结点的单链表。

裁判测试程序样例:

//库函数头文件包含
#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L_Rec(LinkList &L,int n)
{
//递归边界:创建空表时只需将L赋空即可;
//递归关系:创建非空表时,将链表看做两部分:首元素组成的子表La, 第二个元素及其后元素构成的子表Lb。
//子表La容易创建(只需开辟一个节点)
//子表Lb由于规模小可以递归创建完成(类似数学归纳法的假设,只要小的都可以建设能完成)
//最后将两个子表拼接即可。
  LNode *La, *Lb;
  if(n==0) L=NULL;
  else{
    La=(LNode *)malloc(sizeof(LNode));  //开辟子表La
    if(!La) exit(OVERFLOW);
    scanf("%d",&La->data);
    ListCreate_L_Rec(Lb,n-1 ); //递归创建子表Lb
    La->next = Lb;  //两个子表拼结
    L=La;  //第一个子表的地址赋给L。请思考为什这样处理不会使得主函数中的L取错值?
  }
  return OK;
}
void ListPrint_L_Rec(LinkList L);

int main()
{
    LinkList L;
    int n;
    scanf("%d",&n);
    if(ListCreate_L_Rec(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
    ListPrint_L_Rec (L);
    return 0;
}
/* 请在这里填写答案 */

输入格式

第一行输入一个整数n,表示单链表中元素个数,接下来一行共n个整数,中间用空格隔开。

输出格式

递归输出链表的各个元素,每个元素前都有一个用空格,首元素元素前面也有空格。

输入样例:

4
1 2 3 4

输出样例:

1 2 3 4

 

#include
#include
#include

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L_Rec(LinkList &L,int n)
{
//递归边界:创建空表时只需将L赋空即可;
//递归关系:创建非空表时,将链表看做两部分:首元素组成的子表La, 第二个元素及其后元素构成的子表Lb。
//子表La容易创建(只需开辟一个节点)
//子表Lb由于规模小可以递归创建完成(类似数学归纳法的假设,只要小的都可以建设能完成)
//最后将两个子表拼接即可。
  LNode *La, *Lb;
  if(n==0) L=NULL;
  else{
    La=(LNode *)malloc(sizeof(LNode));  //开辟子表La
    if(!La) exit(OVERFLOW);
    scanf("%d",&La->data);
    ListCreate_L_Rec(Lb,n-1 ); //递归创建子表Lb
    La->next = Lb;  //两个子表拼结
    L=La;  //第一个子表的地址赋给L。请思考为什这样处理不会使得主函数中的L取错值?
  }
  return OK;
}
void ListPrint_L_Rec(LinkList L);

int main()
{
    LinkList L;
    int n;
    scanf("%d",&n);
    if(ListCreate_L_Rec(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
    ListPrint_L_Rec (L);
    return 0;
}



void ListPrint_L_Rec(LinkList L)
{
    if(L==NULL) return;
    printf(" %d",L->data);
    ListPrint_L_Rec(L->next);
}

//首先声明一下,这个题目的重点,不是他让你求得,而是他题目中给出的你的代码,如何递归创造一个单链表

 

#include 
#include 

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree CreatBinTree(); /* 实现细节忽略 */
int GetHeight( BinTree BT );

int main()
{
    BinTree BT = CreatBinTree();
    printf("%d\n", GetHeight(BT));
    return 0;
}
/* 你的代码将被嵌在这里 */

int GetHeight( BinTree BT )
{
    int len1,len2;
    if(BT==NULL) return 0;
    len1=GetHeight(BT->Left);
    len2=GetHeight(BT->Right);
    if(len1>len2) return len1+1;
    else return len2+1;
}
//注意这个题的思路并不难,只是递归结构比较难想。遍历左右子树,然后选取最大值,从头到底

 

 

6-181 二叉树的遍历 (25 分)

本题要求给定二叉树的4种遍历。

函数接口定义:

void InorderTraversal( BinTree BT );
void PreorderTraversal( BinTree BT );
void PostorderTraversal( BinTree BT );
void LevelorderTraversal( BinTree BT );

其中BinTree结构定义如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

要求4个函数分别按照访问顺序打印出结点的内容,格式为一个空格跟着一个字符。

裁判测试程序样例:

#include 
#include 

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree CreatBinTree(); /* 实现细节忽略 */
void InorderTraversal( BinTree BT );
void PreorderTraversal( BinTree BT );
void PostorderTraversal( BinTree BT );
void LevelorderTraversal( BinTree BT );

int main()
{
    BinTree BT = CreatBinTree();
    printf("Inorder:");    InorderTraversal(BT);    printf("\n");
    printf("Preorder:");   PreorderTraversal(BT);   printf("\n");
    printf("Postorder:");  PostorderTraversal(BT);  printf("\n");
    printf("Levelorder:"); LevelorderTraversal(BT); printf("\n");
    return 0;
}
/* 你的代码将被嵌在这里 */

输出样例(对于图中给出的树):

Inorder: D B E F A G H C I
Preorder: A B D F E C G H I
Postorder: D E F B H G I C A
Levelorder: A B C D F G I E H

 

void InorderTraversal( BinTree BT )
{
    if(BT!=NULL)
    {
        InorderTraversal(BT->Left);
        printf(" %c",BT->Data);
        InorderTraversal(BT->Right);
    }

}


void PreorderTraversal( BinTree BT )
{

    if(BT!=NULL)
    {
        printf(" %c",BT->Data);
        PreorderTraversal(BT->Left);
        PreorderTraversal(BT->Right);
    }
}


void PostorderTraversal( BinTree BT )
{
    if(BT!=NULL)
    {
        PostorderTraversal(BT->Left);
        PostorderTraversal(BT->Right);
        printf(" %c",BT->Data);
    }
}

void LevelorderTraversal( BinTree BT )
{
    if(BT==NULL) return;

    BinTree t[10000];
    int l=0,r=0;
    t[r++]=BT;


    while(lData);
        if(p->Left!=NULL) t[r++]=p->Left;
        if(p->Right!=NULL) t[r++]=p->Right;
    }

}
//四种遍历方式

 

 

6-3 先序输出叶结点 (15 分)

本题要求按照先序遍历的顺序输出给定二叉树的叶结点。

函数接口定义:

void PreorderPrintLeaves( BinTree BT );

其中BinTree结构定义如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

函数PreorderPrintLeaves应按照先序遍历的顺序输出给定二叉树BT的叶结点,格式为一个空格跟着一个字符。

裁判测试程序样例:

#include 
#include 

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree CreatBinTree(); /* 实现细节忽略 */
void PreorderPrintLeaves( BinTree BT );

int main()
{
    BinTree BT = CreatBinTree();
    printf("Leaf nodes are:");
    PreorderPrintLeaves(BT);
    printf("\n");

    return 0;
}
/* 你的代码将被嵌在这里 */

输出样例(对于图中给出的树):

Leaf nodes are: D E H I
#include 
#include 

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree CreatBinTree(); /* 实现细节忽略 */
void PreorderPrintLeaves( BinTree BT );

int main()
{
    BinTree BT = CreatBinTree();
    printf("Leaf nodes are:");
    PreorderPrintLeaves(BT);
    printf("\n");

    return 0;
}

void PreorderPrintLeaves( BinTree BT )
{
    if(BT!=NULL)
    {
        if(BT->Left==NULL&&BT->Right==NULL) printf(" %c",BT->Data);
        PreorderPrintLeaves(BT->Left);
        PreorderPrintLeaves(BT->Right);
    }
}

 

6-248 邻接矩阵存储图的深度优先遍历 (20 分)

试实现邻接矩阵存储图的深度优先遍历。

函数接口定义:

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );

其中MGraph是邻接矩阵存储的图,定义如下:

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;  /* 顶点数 */
    int Ne;  /* 边数   */
    WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */

函数DFS应从第V个顶点出发递归地深度优先遍历图Graph,遍历时用裁判定义的函数Visit访问每个顶点。当访问邻接点时,要求按序号递增的顺序。题目保证V是图中的合法顶点。

裁判测试程序样例:

#include 

typedef enum {false, true} bool;
#define MaxVertexNum 10  /* 最大顶点数设为10 */
#define INFINITY 65535   /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex;      /* 用顶点下标表示顶点,为整型 */
typedef int WeightType;  /* 边的权值设为整型 */

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;  /* 顶点数 */
    int Ne;  /* 边数   */
    WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
bool Visited[MaxVertexNum]; /* 顶点的访问标记 */

MGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */

void Visit( Vertex V )
{
    printf(" %d", V);
}

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );


int main()
{
    MGraph G;
    Vertex V;

    G = CreateGraph();
    scanf("%d", &V);
    printf("DFS from %d:", V);
    DFS(G, V, Visit);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:给定图如下

5

输出样例:

DFS from 5: 5 1 3 0 2 4 6
#include 

typedef enum {false, true} bool;
#define MaxVertexNum 10  /* 最大顶点数设为10 */
#define INFINITY 65535   /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex;      /* 用顶点下标表示顶点,为整型 */
typedef int WeightType;  /* 边的权值设为整型 */

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;  /* 顶点数 */
    int Ne;  /* 边数   */
    WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
bool Visited[MaxVertexNum]; /* 顶点的访问标记 */

MGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */

void Visit( Vertex V )
{
    printf(" %d", V);
}

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );


int main()
{
    MGraph G;
    Vertex V;

    G = CreateGraph();
    scanf("%d", &V);
    printf("DFS from %d:", V);
    DFS(G, V, Visit);

    return 0;
}


void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )
{
    Visited[V]=true;
    Visit(V);
    for(int i=0;iNv;i++)
    {
        if(Graph->G[V][i]==1&&Visited[i]!=true)
            DFS(Graph,i,Visit);
    }
}
//注意这里if的判断条件,只能是G【】【】==1,这个主要是看你Creat函数是如何创建的,这里并未给出,所以很难去猜,考试的时候背上就行

 

 

6-249 邻接表存储图的广度优先遍历 (20 分)

试实现邻接表存储图的广度优先遍历。

函数接口定义:

void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) );

其中LGraph是邻接表存储的图,定义如下:

/* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;        /* 邻接点下标 */
    PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
};

/* 顶点表头结点的定义 */
typedef struct Vnode{
    PtrToAdjVNode FirstEdge; /* 边表头指针 */
} AdjList[MaxVertexNum];     /* AdjList是邻接表类型 */

/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;     /* 顶点数 */
    int Ne;     /* 边数   */
    AdjList G;  /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */

函数BFS应从第S个顶点出发对邻接表存储的图Graph进行广度优先搜索,遍历时用裁判定义的函数Visit访问每个顶点。当访问邻接点时,要求按邻接表顺序访问。题目保证S是图中的合法顶点。

裁判测试程序样例:

#include 


#define MaxVertexNum 10   /* 最大顶点数设为10 */
typedef int Vertex;       /* 用顶点下标表示顶点,为整型 */

/* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;        /* 邻接点下标 */
    PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
};

/* 顶点表头结点的定义 */
typedef struct Vnode{
    PtrToAdjVNode FirstEdge; /* 边表头指针 */
} AdjList[MaxVertexNum];     /* AdjList是邻接表类型 */

/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;     /* 顶点数 */
    int Ne;     /* 边数   */
    AdjList G;  /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */

bool Visited[MaxVertexNum]; /* 顶点的访问标记 */

LGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */

void Visit( Vertex V )
{
    printf(" %d", V);
}

void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) );

int main()
{
    LGraph G;
    Vertex S;

    G = CreateGraph();
    scanf("%d", &S);
    printf("BFS from %d:", S);
    BFS(G, S, Visit);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:给定图如下

数据结构期末考试复习资料(函数题)_第1张图片

2

输出样例:

BFS from 2: 2 0 3 5 4 1 6
#include 

#define MaxVertexNum 10   /* 最大顶点数设为10 */
typedef int Vertex;       /* 用顶点下标表示顶点,为整型 */

/* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
    Vertex AdjV;        /* 邻接点下标 */
    PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
};

/* 顶点表头结点的定义 */
typedef struct Vnode{
    PtrToAdjVNode FirstEdge; /* 边表头指针 */
} AdjList[MaxVertexNum];     /* AdjList是邻接表类型 */

/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;     /* 顶点数 */
    int Ne;     /* 边数   */
    AdjList G;  /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */

bool Visited[MaxVertexNum]; /* 顶点的访问标记 */

LGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */

void Visit( Vertex V )
{
    printf(" %d", V);
}

void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) );

int main()
{
    LGraph G;
    Vertex S;

    G = CreateGraph();
    scanf("%d", &S);
    printf("BFS from %d:", S);
    BFS(G, S, Visit);

    return 0;
}

void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) )
{
     Vertex que[10000];
     int l=0,r=0;
     que[r++]=S;
     Visited[S]=true;
     Visit(S);

     while(lG[v].FirstEdge;
         while(t!=NULL)
         {
             if(Visited[t->AdjV]!=true)
             {
                 que[r++]=t->AdjV;
                 Visit(t->AdjV);
                 Visited[t->AdjV]=true;
             }
             t=t->Next;
         }
     }
}
//注意BFS是对队列的模拟,还有就是到底应该建立一个什么类型的变量t来储存邻接链表,注意什么时候用->什么时候用.

 

你可能感兴趣的:(数据结构)