(免费)anyview答案 数据结构(C语言版)-广工(第二章)

目录

DC02PE03

DC02PE05

DC02PE07

DC02PE11

DC02PE13

DC02PE15

DC02PE17

DC02PE19

DC02PE20

DC02PE21

DC02PE23

DC02PE25

DC02PE27

DC02PE32

DC02PE33

DC02PE35

DC02PE45

DC02PE53

DC02PE55

DC02PE61

DC02PE63

DC02PE68

DC02PE71

DC02PE73

DC02PE75

DC02PE77

DC02PE82

DC02PE84

DC02PE86

DC02PE88

DC02PE90

DC02PE91

DC02PE93

DC02PE94

DC02PE95

DC02PE97

DC02PE98


自己乱写的代码,希望有大佬指导一下~

DC02PE03

实现顺序栈的判空操作

【题目】试写一算法,实现顺序栈的判空操作。
StackEmpty_Sq(SqStack S)。

要求实现下列函数:
Status StackEmpty_Sq(SqStack S); 
/* 对顺序栈S判空。                      */ 
/* 若S是空栈,则返回TRUE;否则返回FALSE */

顺序栈的类型定义为:
typedef struct {
  ElemType *elem;  // 存储空间的基址
  int top;         // 栈顶元素的下一个位置,简称栈顶位标
  int size;        // 当前分配的存储容量
  int increment;   // 扩容时,增加的存储容量
} SqStack;         // 顺序栈

Status StackEmpty_Sq(SqStack S) {
     if (S.top==0) {
       return TRUE;
     }
     else {
       return FALSE;
     }
   }

DC02PE05

实现顺序栈的取栈顶元素操作

[20230210]试写一算法,实现顺序栈的取栈顶元素操作。
GetTop_Sq(SqStack S, ElemType &e)。

要求实现下列函数:
Status GetTop_Sq(SqStack S, ElemType &e);
/* 取顺序栈S的栈顶元素到e,并返回OK; */ 
/* 若失败,则返回ERROR。              */

顺序栈的类型定义为:
typedef struct {
  ElemType *elem;  // 存储空间的基址
  int top;         // 栈顶元素的下一个位置,简称栈顶位标
  int size;        // 当前分配的存储容量
  int increment;   // 扩容时,增加的存储容量
} SqStack;         // 顺序栈

Status GetTop_Sq(SqStack S, ElemType &e) {
  if (S.top==0) {
    return ERROR;
  }
  else {
    e=S.elem[--(S.top)];
    return OK;
  }
}

DC02PE07

实现顺序栈的出栈操作

【题目】试写一算法,实现顺序栈的出栈操作。
Pop_Sq(SqStack &S, ElemType &e)。

要求实现下列函数:
Status Pop_Sq(SqStack &S, ElemType &e); 
/* 顺序栈S的栈顶元素出栈到e,并返回OK;*/ 
/* 若失败,则返回ERROR。               */

顺序栈的类型定义为:
typedef struct {
  ElemType *elem;  // 存储空间的基址
  int top;         // 栈顶元素的下一个位置,简称栈顶位标
  int size;        // 当前分配的存储容量
  int increment;   // 扩容时,增加的存储容量
} SqStack;         // 顺序栈

Status Pop_Sq(SqStack &S, ElemType &e) {
     if (S.top==0) {
       return ERROR;
     }
     else {
       e=S.elem[--(S.top)];
       return OK;
     }
   }

DC02PE11

构建初始容量和扩容增量分别为size和inc的空顺序栈S

【题目】若顺序栈的类型重新定义如下。试编写算法,构建初始容量和扩容增量分别为size和inc的空顺序栈S。

typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

要求实现下列函数:
Status InitStack_Sq2(SqStack2 &S, int size, int inc); 
/* 构建初始容量和扩容增量分别为size和inc的空顺序栈S。*/ 
/* 若成功,则返回OK;否则返回ERROR。                 */

Status InitStack_Sq2(SqStack2 &S, int size, int inc) {
     S.elem=(ElemType*)malloc(sizeof(ElemType)*size);
     if (!S.elem||inc<0) {
       return ERROR;
     }
     S.top=S.elem;
     S.size=size;
     S.increment=inc;
     return OK;
   }

DC02PE13

实现顺序栈的判空操作

【题目】若顺序栈的类型重新定义如下。试编写算法,实现顺序栈的判空操作。
typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

要求实现下列函数:
Status StackEmpty_Sq2(SqStack2 S); 
/* 对顺序栈S判空。                      */ 
/* 若S是空栈,则返回TRUE;否则返回FALSE */

Status StackEmpty_Sq2(SqStack2 S) {
     if (S.elem==S.top) {
       return TRUE;
     }
     else {
       return FALSE;
     }
   }

DC02PE15

实现顺序栈的入栈操作

【题目】若顺序栈的类型重新定义如下。试编写算法,实现顺序栈的入栈操作。
typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

要求实现下列函数:
Status Push_Sq2(SqStack2 &S, ElemType e); 
/* 若顺序栈S是满的,则扩容,若失败则返回ERROR。*/
/* 将e压入S,返回OK。                          */

Status Push_Sq2(SqStack2 &S, ElemType e) {
     if (S.top-S.elem>=S.size) {
       ElemType*pnew=(ElemType*)realloc(S.elem,sizeof(ElemType)*(S.increment+S.size));
       if (!pnew) {
         return ERROR;
       }
       S.elem=pnew;
       S.top=S.elem+S.size;
       S.size+=S.increment;
     }
     *(S.top++)=e;
     return OK;
   }

DC02PE17

实现顺序栈的出栈操作

【题目】若顺序栈的类型重新定义如下。试编写算法,实现顺序栈的出栈操作。
typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

要求实现下列函数:
Status Pop_Sq2(SqStack2 &S, ElemType &e); 
/* 若顺序栈S是空的,则返回ERROR;    */ 
/* 否则将S的栈顶元素出栈到e,返回OK。*/

Status Pop_Sq2(SqStack2 &S, ElemType &e) {     
   if (S.top==S.elem) {
      return ERROR;
   }
   e=*(--(S.top));
   S.size--;
   return OK;
 }

DC02PE19

借助辅助栈,复制顺序栈S1得到S2

【题目】试写一算法,借助辅助栈,复制顺序栈S1得到S2。
Status CopyStack_Sq(SqStack S1, SqStack &S2)。

要求实现下列函数:
Status CopyStack_Sq(SqStack S1, SqStack &S2); 
/* 借助辅助栈,复制顺序栈S1得到S2。    */ 
/* 若复制成功,则返回TRUE;否则FALSE。 */

顺序栈的类型定义为:
typedef struct {
  ElemType *elem;  // 存储空间的基址
  int top;         // 栈顶元素的下一个位置,简称栈顶位标
  int size;        // 当前分配的存储容量
  int increment;   // 扩容时,增加的存储容量
} SqStack;         // 顺序栈
可调用顺序栈接口中下列函数:
Status InitStack_Sq(SqStack &S, int size, int inc); // 初始化顺序栈S
Status DestroyStack_Sq(SqStack &S); // 销毁顺序栈S
Status StackEmpty_Sq(SqStack S);    // 栈S判空,若空则返回TRUE,否则FALSE
Status Push_Sq(SqStack &S, ElemType e); // 将元素e压入栈S
Status Pop_Sq(SqStack &S, ElemType &e); // 栈S的栈顶元素出栈到e

Status CopyStack_Sq(SqStack S1, SqStack &S2) {
    // 初始化辅助栈
    SqStack tempStack;
    if (!InitStack_Sq(tempStack, S1.size, S1.increment)) 
        return FALSE;
    
    // 初始化目标栈S2
    if (!InitStack_Sq(S2, S1.size, S1.increment)) {
        DestroyStack_Sq(tempStack);
        return FALSE;
    }
    
    // 临时保存S1的元素到辅助栈
    ElemType e;
    SqStack S1Copy = S1;  // 创建S1的副本以避免修改原栈
    
    while (!StackEmpty_Sq(S1Copy)) {
        if (!Pop_Sq(S1Copy, e)) {
            DestroyStack_Sq(tempStack);
            DestroyStack_Sq(S2);
            return FALSE;
        }
        if (!Push_Sq(tempStack, e)) {
            DestroyStack_Sq(tempStack);
            DestroyStack_Sq(S2);
            return FALSE;
        }
    }
    
    // 将辅助栈的元素依次压入S2和S1
    while (!StackEmpty_Sq(tempStack)) {
        if (!Pop_Sq(tempStack, e)) {
            DestroyStack_Sq(tempStack);
            DestroyStack_Sq(S2);
            return FALSE;
        }
        if (!Push_Sq(S2, e) || !Push_Sq(S1Copy, e)) {
            DestroyStack_Sq(tempStack);
            DestroyStack_Sq(S2);
            return FALSE;
        }
    }
    
    DestroyStack_Sq(tempStack);
    return TRUE;
}

DC02PE20

数制转换:将十进制数转换为指定进制的数

[20220901]编写程序,将一个十进制数转换为指定进制的数。

/**
   * 将整数N转换为有rd指定的进制,并将结果打印出来。
   * @param  N: 需要被转换的十进制数
   * @param  rd: 取值为[2~9],表示具体的进制,例如rd = 8时,表示八进制
   */
void Conversion(int N, int rd);

注:请勿打印除了结果之外的其它任何字符,否则可能导致结果校验错误。

有以下数据结构及其操作可用:

#define MAXSIZE 20
#define INCREMENT 5

typedef int Status;

typedef char ElemType;
typedef struct {
  ElemType *elem; // 存储空间的基址
  int top;        // 栈顶元素的下一个位置,简称栈顶位标
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack;        // 顺序栈

// 初始化一个栈,size为栈的初始容量,inc为栈增容时的容量。一般而言,可令size为MAXSIZE,inc为INCREMENT
Status InitStack_Sq(SqStack &S, int size, int inc); 
// 销毁栈
Status DestroyStack_Sq(SqStack S);
//检查栈是否为空。如果为空,则返回TRUE,否则返回FALSE
Status StackEmpty_Sq(SqStack S) ;
//将元素e进栈
Status Push_Sq(SqStack &S, ElemType e) ;
//出栈,并且栈顶元素赋给e
Status Pop_Sq(SqStack &S, ElemType &e);

void Conversion(int N, int rd){  
   SqStack S;
   InitStack_Sq(S,MAXSIZE,INCREMENT);
   int temp=N;
   while (temp) {
      Push_Sq(S,temp%rd);
      temp=temp/rd;
   }
   while (!StackEmpty_Sq(S)) {
      char i;
      Pop_Sq(S,i);
      printf("%d",i);
   }
 }

DC02PE21

判断一个括号串中的括号是否匹配

编写程序,判断一个括号串中的括号是否匹配。括号有3种:{}、[]、()。

/**
   * 判断一个括号串中的括号是否为匹配。
   * @param  exp: 括号串
   * @param  n: 括号串的长度
   */
Status matchBracketSequence(char* exp, int n);

有以下数据结构及其操作可用:

#define MAXSIZE 20
#define INCREMENT 5

typedef int Status;

typedef char ElemType;
typedef struct {
  ElemType *elem; // 存储空间的基址
  int top;        // 栈顶元素的下一个位置,简称栈顶位标
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack;        // 顺序栈

// 初始化一个栈,size为栈的初始容量,inc为栈增容时的容量。一般而言,可令size为MAXSIZE,inc为INCREMENT
Status InitStack_Sq(SqStack &S, int size, int inc); 
// 销毁栈
Status DestroyStack_Sq(SqStack S);
//检查栈是否为空。如果为空,则返回TRUE,否则返回FALSE
Status StackEmpty_Sq(SqStack S) ;
//将元素e进栈
Status Push_Sq(SqStack &S, ElemType e) ;
//出栈,并且栈顶元素赋给e
Status Pop_Sq(SqStack &S, ElemType &e);
//将栈顶元素赋给e,但栈顶元素不出栈
Status GetTop_Sq(SqStack& S, ElemType& e);

Status matchBracketSequence(char* exp, int n) {
    // 初始化栈
    SqStack S;
    if (!InitStack_Sq(S, MAXSIZE, INCREMENT)) {
        return FALSE; // 初始化失败
    }
    
    for (int i = 0; i < n; i++) {
        char c = exp[i];
        // 如果是左括号,入栈
        if (c == '{' || c == '[' || c == '(') {
            if (!Push_Sq(S, c)) {
                DestroyStack_Sq(S); // 入栈失败,销毁栈并返回不匹配
                return FALSE;
            }
        } 
        // 如果是右括号,检查是否匹配
        else if (c == '}' || c == ']' || c == ')') {
            char top;
            if (StackEmpty_Sq(S)) {
                DestroyStack_Sq(S); // 栈为空,不匹配
                return FALSE;
            }
            Pop_Sq(S, top); // 弹出栈顶元素
            
            // 检查括号是否匹配
            if ((c == '}' && top != '{') || 
                (c == ']' && top != '[') || 
                (c == ')' && top != '(')) {
                DestroyStack_Sq(S); // 不匹配
                return FALSE;
            }
        }
    }
    
    // 最后检查栈是否为空
    Status isEmpty = StackEmpty_Sq(S);
    DestroyStack_Sq(S);
    
    return isEmpty; // 栈为空则匹配,否则不匹配
}

DC02PE23

求循环队列的长度

【题目】试编写算法,求循环队列的长度。
循环队列的类型定义为:
typedef struct {
  ElemType *base;  // 存储空间的基址
  int front;       // 队头位标
  int rear;        // 队尾位标,指示队尾元素的下一位置
  int maxSize;     // 最大长度
} SqQueue;

要求实现下列函数:
int QueueLength_Sq(SqQueue Q); 
/* 返回队列Q中元素个数,即队列的长度。*/

int QueueLength_Sq(SqQueue Q) {     
  return (Q.rear-Q.front+Q.maxSize)%Q.maxSize;
}

DC02PE25

编写入队列和出队列的算法

【题目】如果希望循环队列中的元素都能得到利用,则可设置一个标志域tag,并以tag值为0或1来区分尾指针和头指针值相同时的队列状态是"空"还是"满"。试编写与此结构相应的入队列和出队列的算法。

注:如果队列为空,则需保证标志域tag的值为0;如果队列已满,则需保证标志域tag的值为1。否则,程序运行后会无输出,导致不能通过。

本题的循环队列CTagQueue的类型定义如下:
typedef struct {
  ElemType elem[MAXQSIZE];
  int tag;
  int front;
  int rear;
} CTagQueue;

实现下列函数:
Status EnCQueue(CTagQueue &Q, ElemType x);
  /* 将元素x加入队列Q,并返回OK;*/
  /* 若失败,则返回ERROR。       */
Status DeCQueue(CTagQueue &Q, ElemType &x);
  /* 将队列Q的队头元素退队到x,并返回OK;*/
  /* 若失败,则返回ERROR。               */

Status EnCQueue(CTagQueue &Q, ElemType x) {
    if (Q.tag==1&&(Q.rear==Q.front)){
        return ERROR;
    }
    Q.elem[Q.rear]=x;
    Q.rear=(Q.rear+1)%MAXQSIZE;
    if (Q.rear==Q.front) {
        Q.tag=1;
    }
    return OK;
  }
Status DeCQueue(CTagQueue &Q, ElemType &x){   
  if (Q.tag==0&&Q.rear==Q.front) {
    return ERROR;
  }
  x=Q.elem[Q.front];
  Q.front=(Q.front+1)%MAXQSIZE;
  if (Q.rear==Q.front) {
    Q.tag==0;
  }
  return OK;
}

DC02PE27

写出循环队列的入队列和出队列的算法

【题目】假设将循环队列定义为:以域变量rear和length分别指示循环队列中队尾元素的位置和内含元素的个数。试给出此循环队列的队满条件,并写出相应的入队列和出队列的算法(在出队列的算法中要返回队头元素)。

本题的循环队列CLenQueue的类型定义如下:
typedef struct {
  ElemType elem[MAXQSIZE];
  int length;
  int rear;
} CLenQueue;

实现下列函数:
Status EnCQueue(CLenQueue &Q, ElemType x);
  /* 将元素x加入队列Q,并返回OK;*/
  /* 若失败,则返回ERROR。       */
Status DeCQueue(CLenQueue &Q, ElemType &x);
  /* 将队列Q的队头元素退队到x,并返回OK;*/
  /* 若失败,则返回ERROR。               */

Status EnCQueue(CLenQueue &Q, ElemType x) {
     if (Q.length==MAXQSIZE) {
       return ERROR;
     }
     Q.rear=(Q.rear+1)%MAXQSIZE;
     Q.elem[Q.rear]=x;
     Q.length++;
     return OK;
  }
Status DeCQueue(CLenQueue &Q, ElemType &x){
    if (0==Q.length) {
      return ERROR;
    }
    int front=(Q.rear-Q.length+MAXQSIZE+1)%MAXQSIZE;
    x=Q.elem[front];
    Q.length--;
    return OK;
  }

DC02PE32

利用循环队列编写求k阶斐波那契序列中第n+1项fn的算法

【题目】已知k阶斐波那契序列的定义为:
    f0=0,  f1=0,  …,  fk-2=0,  fk-1=1;
    fn=fn-1+fn-2+…+fn-k,  n=k,k+1,…
试利用循环队列编写求k阶斐波那契序列中第n+1项fn的算法。

本题的循环队列的类型定义如下:
typedef struct {
  ElemType *base; // 存储空间的基址
  int front;      // 队头位标
  int rear;       // 队尾位标,指示队尾元素的下一位置
  int maxSize;    // 最大长度
} SqQueue;

要求实现下列函数:
long Fib(int k, int n);
/* 求k阶斐波那契序列的第n+1项fn */

本题未给出循环队列的相关函数,推荐使用递归算法完成

long Fib(int k, int n) {  
    if (n<k-1) {
        return 0;
    }
    else if (n==k-1){
        return 1;
    }
    else {
        int result=0;
        for (int i = 1; i <=k; i++) {
            result+=Fib(k,n-i);
        }
    return result;
    }
 }

DC02PE33

比较两个有序顺序表的大小

【题目】设A=(a1,…,am)和B=(b1,…,bn)均为有序顺序表,A'和B'分别为A和B中除去最大共同前缀后的子表(例如,A=(x,y,y,z,x,z),B=(x,y,y,z,y,x,x,z),则两者中最大的共同前缀为(x,y,y,z), 在两表中除去最大共同前缀后的子表分别为A'=(x,z)和B'=(y,x,x,z))。若A'=B'=空表,则A=B;若A'=空表,而B'≠ 空表,或者两者均不为空表,且A'的首元小于B'的首元,则A<B;否则A>B。试写一个比较A和B大小的算法。(注意:在算法中,不要破坏原表A和B,也不一定先求得A'和B'才可以进行比较)。

顺序表类型定义如下:
typedef struct {
  ElemType *elem;
  int       length;
  int       size;
  int       increment;
} SqList;

要求实现下列函数:
char Compare(SqList A, SqList B);
/* 比较顺序表A和B,      */
/*   返回'<', 若A<B;    */
/*       '=', 若A=B;    */
/*       '>', 若A>B     */

char Compare(SqList A, SqList B) { 
    int i = 0;
    while (i < A.length && i < B.length && A.elem[i] == B.elem[i]) {
        i++;
    }
    if (i == A.length && i == B.length) {
        return '=';
    } 
    else if (i == A.length) {
        return '<';
    } 
    else if (i == B.length) {
        return '>';
    } 
    else if (A.elem[i] < B.elem[i]) {
        return '<';
    }
    return '>';
  }

DC02PE35

试写一算法,实现顺序表的就地逆置

【题目】试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,a2,…,an)逆置为(an,an-1,…,a1)。

顺序表类型定义如下:
typedef struct {
  ElemType *elem;
  int       length;
  int       size;
  int       increment;
} SqList;

实现下列函数:
void Inverse(SqList &L);

void Inverse(SqList &L) { 
  int left=0;
  int right=L.length-1;
  while (left<right) {
      ElemType temp=L.elem[left];
      L.elem[left]=L.elem[right];
      L.elem[right]=temp;
      left++;
      right--;
  }
}

DC02PE45

试写一算法,求并集A=A∪B。

【20231030题目】假设有两个集合A和B分别用两个线性表LA和LB表示(即:线性表中的数据元素即为集合中的成员),试写一算法,求并集A=A∪B。

顺序表类型定义如下
typedef struct {
   ElemType *elem;  // 存储空间的基址
   int length;    // 当前长度
   int size;      // 存储容量 
   int increment; // 空间不够增加空间大小
} SqList;  // 顺序表

可调用顺序表的以下接口函数:   
  Status InitList_Sq(SqList &L, int size, int inc); // 初始化顺序表L
  int ListLength_Sq(SqList L);  // 返回顺序表L中元素个数
  Status GetElem_Sq(SqList L, int i, ElemType &e); 
  // 用e返回顺序表L中第i个元素的值
  int Search_Sq(SqList L, ElemType e); 
  // 在顺序表L顺序查找元素e,成功时返回该元素在表中第一次出现的位置,否则返回-1
  Status Append_Sq(SqList &L, ElemType e);  // 在顺序表L表尾添加元素e

实现如下算法:
void Union(SqList &La, List Lb)

void Union(SqList &La, List Lb){ 
    int La_len = ListLength_Sq(La);
    int Lb_len = ListLength_Sq(Lb);
    ElemType e;
    for (int i = 1; i <= Lb_len; i++) {
        GetElem_Sq(Lb, i, e);
        if (Search_Sq(La, e) == -1) {
            Append_Sq(La, e);
        }
    }
  }

DC02PE53

试写一算法,实现链栈的判空操作。

【题目】试写一算法,实现链栈的判空操作。

链栈的类型定义为:
typedef struct LSNode {
  ElemType data;       // 数据域
  struct LSNode *next; // 指针域
} LSNode, *LStack; // 结点和链栈类型

要求实现下列函数:
Status StackEmpty_L(LStack S); 
/* 对链栈S判空。若S是空栈,则返回TRUE;否则返回FALSE */

Status StackEmpty_L(LStack S) {
    if (S) {
      return FALSE;
    }
    if (S==NULL||S->next==NULL) {
    return TRUE;
    }
    return FALSE;
  }

DC02PE55

试写一算法,实现链栈的取栈顶元素操作

【题目】试写一算法,实现链栈的取栈顶元素操作。

链栈的类型定义为:
typedef struct LSNode {
  ElemType data;       // 数据域
  struct LSNode *next; // 指针域
} LSNode, *LStack; // 结点和链栈类型

要求实现下列函数:
Status GetTop_L(LStack S, ElemType &e); 
/* 取链栈S的栈顶元素到e,并返回OK; */
/* 若S是空栈,则失败,返回ERROR。  */

Status GetTop_L(LStack S, ElemType &e) {
    if (!S) {
      return ERROR;
    }
    e=(S->data);
    return OK;
  }

DC02PE61

实现链队列的判空操作

【题目】试写一算法,实现链队列的判空操作。

链队列的类型定义为:
typedef struct LQNode {     
  ElemType  data;  
  struct LQNode  *next;  
} LQNode, *QueuePtr; // 结点和结点指针类型
typedef struct {     
  QueuePtr  front;  // 队头指针
  QueuePtr  rear;   // 队尾指针
} LQueue;  // 链队列类型

要求实现下列函数:
Status QueueEmpty_LQ(LQueue Q);
/* 判定链队列Q是否为空队列。           */
/* 若Q是空队列,则返回TRUE,否则FALSE。*/

Status QueueEmpty_LQ(LQueue Q){
   if (Q.front) {
     return FALSE;
   }
   if (Q.rear==Q.front) {
     return TRUE;
   }
   return FALSE;
 }

DC02PE63

实现链队列的求队列长度操作

【题目】试写一算法,实现链队列的求队列长度操作。

链队列的类型定义为:
typedef struct LQNode {     
  ElemType  data;  
  struct LQNode  *next;  
} LQNode, *QueuePtr; // 结点和结点指针类型
typedef struct {     
  QueuePtr  front;  // 队头指针
  QueuePtr  rear;   // 队尾指针
} LQueue;  // 链队列类型

要求实现下列函数:
int QueueLength_LQ(LQueue Q);
/* 求链队列Q的长度并返回其值 */

int QueueLength_LQ(LQueue Q) {
   if (!Q.front&&Q.front==Q.rear) {
     return 0;
   }
   int length = 0;
   QueuePtr p = Q.front->next;
   while (p != NULL) {
     length++;
     p = p->next;
   }
   return length+1;
 }

DC02PE68

编写队列初始化、入队列和出队列的算法

【题目】假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。

带头结点循环链队列CLQueue的类型定义为:
typedef char ElemType;
typedef struct CLQNode {     
  ElemType  data;  
  struct CLQNode  *next;  
} CLQNode, *CLQueue; // 结点和结点指针类型

实现下列函数:
Status InitCLQueue(CLQueue &rear); // 初始化空队列
Status EnCLQueue(CLQueue &rear, ElemType x); // 入队
Status DeCLQueue(CLQueue &rear, ElemType &x); // 出队

Status InitCLQueue(CLQueue &rear) {
   rear=(CLQueue)malloc(sizeof(CLQNode));
   if (!rear) {
     return ERROR;
   }
   rear->next=rear;
   return OK;
} 
Status EnCLQueue(CLQueue &rear, ElemType x){
   CLQueue p=(CLQueue)malloc(sizeof(CLQNode));
   if (!p) {
    return ERROR;
   }
   p->data=x;
   p->next=rear->next;
   rear->next=p;
   rear=p;
   return OK;
}
Status DeCLQueue(CLQueue &rear, ElemType &x){
    if (rear->next == rear) return ERROR;
    CLQueue front = rear->next->next;
    x = front->data;
    rear->next->next = front->next;
    if (front == rear) rear = rear->next;
    free(front);
    return OK;
}

DC02PE71

实现带头结点单链表的判空操作。

【题目】试写一算法,实现带头结点单链表的判空操作。

单链表的类型定义为:
typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型

要求实现下列函数:
Status ListEmpty_L(LinkList L);
/* 判定带头结点单链表L是否为空链表。   */
/* 若L是空链表,则返回TRUE,否则FALSE。*/

Status ListEmpty_L(LinkList L) {
    if (L->next==NULL) {
    return TRUE;
    }
    return FALSE;
  }

DC02PE73

实现带头结点单链表的销毁操作

【20220317】试写一算法,实现带头结点单链表的销毁操作。

单链表的类型定义为:
typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型

要求实现下列函数:
Status DestroyList_L(LinkList &L);
/* 销毁带头结点单链表L,并返回OK。*/

Status DestroyList_L(LinkList &L) {
    LNode*p=L;
    while (p) {
      LNode*temp=p;
      p=p->next;
      free(temp);
    }
    L=NULL;
    return OK;
 }

DC02PE75

实现带头结点单链表的清空操作

【题目】试写一算法,实现带头结点单链表的清空操作。

单链表的类型定义为:
typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型

要求实现下列函数:
Status ClearList_L(LinkList &L);
/* 将带头结点单链表L置为空表,并返回OK。*/
/* 若L不是带头结点单链表,则返回ERROR。 */

Status ClearList_L(LinkList &L){
    if (!L) {
      return ERROR;
    }
    LNode*p=L;
    while (p) {
      LNode*temp=p;
      temp->data=NULL;
      p=p->next;
    }
    L->next=NULL;
    return OK;
  }

DC02PE77

实现带头结点单链表的求表长度操作

【题目】试写一算法,实现带头结点单链表的求表长度操作。

单链表的类型定义为:
typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型

要求实现下列函数:
int ListLength_L(LinkList L);
/* 求带头结点单链表L的长度,并返回长度值。*/
/* 若L不是带头结点单链表,则返回-1。      */

int ListLength_L(LinkList L) {
   if (!L) {
     return -1;
   }
   int i;
   LNode*p=L;
   while (p) {
     p=p->next;
     i++;
   }
   return i-1;
}

DC02PE82

在带头结点单链表L的第i个位置插入e。

【题目】试写一算法,在带头结点单链表L的第i个位置插入e。

带头结点单链表的类型定义为:
typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;

实现下列函数:
Status Insert_L(LinkList L, int i, ElemType e);
/* 在带头结点单链表L的第i个位置插入e,并返回OK。*/
/* 若参数不合理,则返回ERROR。              */

Status Insert_L(LinkList L, int i, ElemType e) {
   LNode*p=L;
   int j=0;
   while (p&&j<(i-1)) {
     p=p->next;
     j++;
   }
   if (!p||j>(i-1)) {
     return ERROR;
   }
   LNode*pnew;
   pnew=(LinkList)malloc(sizeof(LNode));
   pnew->data=e;
   pnew->next=p->next;
   p->next=pnew;
   return OK;
 }

DC02PE84

在带头结点单链表删除第i元素到e

【题目】试写一算法,在带头结点单链表L删除第i位置的结点,并用变量e返回该结点的数据元素值。

带头结点单链表的类型定义为:
typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;

实现下列函数:
Status Delete_L(LinkList L, int i, ElemType &e);
/* 在带头结点单链表L删除第i元素到e,并返回OK。*/
/* 若参数不合理,则返回ERROR。                */

Status Delete_L(LinkList L, int i, ElemType &e) {
   if (i<1) {
       return ERROR;
   }
   LNode*p=L;
   int j=0;
   while (p&&j<(i-1)) {
       p=p->next;
       j++;
   }
   if (!p||j>(i-1)||p->next==NULL) {
       return ERROR;
   }
   LNode*dnew;
   dnew=p->next;
   e=dnew->data;
   p->next=dnew->next;
   free(dnew);
   return OK;
 }

DC02PE86

将带头结点单链表的第i元素起的所有元素移除,并构成一个带头结点的新链表。

[20230102] 试写一算法,将带头结点单链表的第i元素起的所有元素从链表移除,并构成一个带头结点的新链表。

带头结点单链表的类型定义为:
typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;

实现下列函数:
Status Split_L(LinkList L, LinkList &Li, int i);
/* 将带头结点单链表L的第i元素起的所有元素 */
/* 移除,并构成带头结点链表Li,返回OK。   */
/* 若参数不合理,则Li为NULL,返回ERROR。  */

Status Split_L(LinkList L, LinkList &Li, int i){
   if (i<1||L==NULL) {
     Li=NULL;
     return ERROR;
   }
   LNode*p=L;
   int j=0;
   while (p&&j<(i-1)) {
     p=p->next;
     j++;
   }
   if (p==NULL||p->next==NULL) {
     Li=NULL; 
     return ERROR;
   }
   Li=(LinkList)malloc(sizeof(LinkList));
   Li->next=p->next;
   p->next=NULL;
   return OK;
 }

DC02PE88

试写一算法,在带头结点单链表删除第i元素起的所有元素。

【题目】试写一算法,在带头结点单链表删除第i元素起的所有元素。

带头结点单链表的类型定义为:
typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;

实现下列函数:
Status Cut_L(LinkList L, int i);
/* 在带头结点单链表L删除第i元素起的所有元素,并返回OK。*/
/* 若参数不合理,则返回ERROR。                         */

Status Cut_L(LinkList L, int i){
  if (!L||i==0) {
    return ERROR;
  }
  int j=0;
  LinkList p=L;
  while (p&&j<i-1) {
    p=p->next;
    j++;
  }
  if (!p||!p->next) {
    return ERROR;
  }
  LNode *q = p->next;    // 释放第 i 个元素起的所有元素的内存
  while (q != NULL) {
    LNode *temp = q;
    q = q->next;
    free(temp);
  }
  p->next=NULL;
  return OK;
}

DC02PE90

删除带头结点单链表中所有值为x的元素

[20220307]试写一算法,删除带头结点单链表中所有值为x的元素,并释放被删结点空间。

单链表类型定义如下:
typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;

实现下列函数:
Status DeleteX_L(LinkList L, ElemType x);
/* 删除带头结点单链表L中所有值为x的元素,      */
/* 并释放被删结点空间,返回实际删除的元素个数。*/

Status DeleteX_L(LinkList L, ElemType x)  {
   if (!L) {
      return 0;
   }
   int a=0;
   LinkList p=L;
   LinkList pv=L;
   while (1) {
      p=p->next;
      if (!p) {
        return a;
      }
      if (p->data==x) {
        pv->next=p->next;
        LinkList d=p;
        p=pv;
        free(d);
        a++;
      }
      else {
        pv=p;
      }
   }
 }

DC02PE91

删除带头结点单链表中所有值小于x的元素

【题目】试写一算法,删除带头结点单链表中所有值小于x的元素,并释放被删结点空间。

单链表类型定义如下:
typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;

实现下列函数:
Status DeleteSome_L(LinkList L, ElemType x);
/* 删除带头结点单链表L中所有值小于x的元素,    */
/* 并释放被删结点空间,返回实际删除的元素个数。*/

Status DeleteSome_L(LinkList L, ElemType x)  {
   if (!L) {
    return 0;
   }
   int a=0;
   LinkList p=L;
   LinkList pv=L;
   while (1) {
       p=p->next;
       if (!p) {
         return a;
       }
       if (p->data<x) {
         pv->next=p->next;
         LinkList d=p;
         p=pv; 
         free(d);
         a++;
       }
       else {
         pv=p;
       }
   }
 }

DC02PE93

删除双向链表中的重复结点

【20220316】试写一算法,删除一条带头结点的链表中所有data域重复的结点,但每种重复的结点都需要保留一个。

// 双向链表的类型定义为:
typedef char  ElemType;

typedef struct DuLNode {     
  ElemType  data;  
  struct DuLNode  *prior, *next;  //分别指向直接前驱和直接后继
} DuLNode, *DuLinkList; // 双向链表

实现下列函数:
DuLinkList delDuplicateDuLNodes(DuLinkList L)
//返回一个无重复结点的双向链表

DuLinkList delDuplicateDuLNodes(DuLinkList L){
    if (L == NULL || L->next == NULL) {
        return L;
    }
    DuLNode *p = L->next;
    while (p != NULL) {
        DuLNode *q = p->next;
        while (q != NULL) {
            if (q->data == p->data) {
                DuLNode *temp = q;
                q->prior->next = q->next;
                if (q->next != NULL) {
                    q->next->prior = q->prior;
                }
                q = q->next;
                free(temp);
            }
            else {
                q = q->next;
            }
        }
        p = p->next;
    }
    return L;
 }

DC02PE94

将一条双向链表逆置

【20220319】试写一算法,将一条带头结点的双向链表逆置。

// 双向链表的类型定义为:
typedef char  ElemType;

typedef struct DuLNode {     
  ElemType  data;  
  struct DuLNode  *prior, *next;  //分别指向直接前驱和直接后继
} DuLNode, *DuLinkList; // 双向链表

实现下列函数:
void reverseDuLinkList(DuLinkList L)
//请将双向链表L逆置

void reverseDuLinkList(DuLinkList L){
   if (!L ||!L->next) {
        return; // 如果链表为空或者只有一个节点,直接返回    
   }
   DuLNode *p = L->next; // 指向第一个数据节点
   DuLNode *temp;    // 先将头节点的 next 和 prior 指针置为 NULL
   L->next = NULL;
   L->prior = NULL;
   while (p) {
        temp = p->next; // 保存下一个节点
        p->next = L->next;
        if (L->next) {
            L->next->prior = p;
        }
        p->prior = L;
        L->next = p;
        p = temp; // 移动到下一个节点
   }
 }

DC02PE95

将一条双向循环链表逆置

【20230830】试写一算法,将一条带头结点的双向循环链表逆置。

// 双向循环链表的类型定义为:
typedef char  ElemType;

typedef struct DuLNode {     
  ElemType  data;  
  struct DuLNode  *prior, *next;  //分别指向直接前驱和直接后继
} DuLNode, *DuLinkList; // 双向链表

typedef DuLinkList DuCirLinkList;  //双向循环链表

实现下列函数:
void reverseDuCirLinkList(DuCirLinkList L)
//请将双向循环链表L逆置

void reverseDuCirLinkList(DuCirLinkList L){
    if (L == NULL || L->next == L) {
        return; // 如果链表为空或只有头结点,无需逆置
    }
    DuLNode *p = L->next;
    DuLNode *temp;
    do {
        temp = p->next;
        p->next = p->prior;
        p->prior = temp;
        p = temp; // 移动到下一个节点
    } while (p != L);    // 最后交换头结点的 prior 和 next 指针
    temp = L->next;
    L->next = L->prior;
    L->prior = temp;
}

DC02PE97

双向交错遍历一条双向循环链表

【202201007】试写一算法,从某个结点p开始,双向交错遍历一条双向循环链表。规定如下:
(1)先从p的next指针域方向最先开始访问;然后访问p的prior域;再访问p的next域...。
(2)已知每个结点的data域只含一个字符。每访问一个结点,就将该结点的data域打印出来。必须使用“%c”格式的printf函数打印。
(3)不打印头结点的data域。如果遍历到头结点,则需沿当前遍历方向,继续前进至下一个结点,并打印该结点的data域。
(4)结点p的data域最后打印,但是如果p是指向头结点,则不打印。
(5)请勿使用printf函数打印其它多余字符,否则可能会导致输出校验出错。
举例:规定头结点为第0个结点,例如从下表中第3个结点开始遍历时:
    0  1  2  3  4  5  6  7  8
       Q  L  F  T  A  R  M  C
打印结果为:TLAQRCMF

实现以下函数:从结点p开始,双向交错遍历L。
void InterleavedTravelDuCirLinkList(DuCirLinkList L, DuLNode* p)

已知双向循环链表的结构体定义:
typedef char  ElemType;

typedef struct DuLNode {     
  ElemType  data;  
  struct DuLNode  *prior, *next;  //分别指向直接前驱和直接后继
} DuLNode, *DuLinkList; // 双向链表

// 双向循环链表:
typedef DuLinkList DuCirLinkList;

 void InterleavedTravelDuCirLinkList(DuCirLinkList L, DuLNode* p){
    if (!L) return; // 统计非头结点个数并把它们按 next 顺序收集到数组中
    int n = 0;
    DuLNode *q = L->next;
    while (q != L) {
        n++;
        q = q->next;
    }
    if (n == 0) return;
    DuLNode **arr = (DuLNode **)malloc(n * sizeof(DuLNode *));
    if (!arr) return;
    int i = 0;
    q = L->next;
    while (q != L) {
        arr[i++] = q;
        q = q->next;
    }
    if (p == L) {
        // p 为头结点:按规则从 p->next(即数组下标0)开始交替取,直到打印完所有 n 个结点
        int printed = 0;
        int r = 0, l = (n - 1);
        int flag = 1;
        while (printed < n) {
            if (flag) {
                printf("%c", arr[r]->data);
                r = (r + 1) % n;
            }
            else {
                printf("%c", arr[l]->data);
                l = (l - 1 + n) % n;
            }
            printed++;
            flag = !flag;
        }
    }
    else {
        // p 不是头结点:先打印除 p 之外的 n-1 个结点(交替取)
        int p_idx = -1;
        for (i = 0; i < n; i++){ 
           if (arr[i] == p) {
                p_idx = i; break;
           }
        }
        if (p_idx == -1) {
                free(arr);
                return;
        } // p 不在链表中(保险判断)
        int to_print = n - 1;
        int printed = 0;
        int r = (p_idx + 1) % n;
        int l = (p_idx - 1 + n) % n;
        int flag = 1; // 首先从 p->next 方向开始(即数组索引 r)
        while (printed < to_print) {
            if (flag) {
                printf("%c", arr[r]->data);
                r = (r + 1) % n;
            }
            else {
                printf("%c", arr[l]->data);
                l = (l - 1 + n) % n;
            }
            printed++;
            flag = !flag;
        }
        // 最后打印 p 的 data(题目规定 p 的 data 最后打印;若 p==L 已在上面处理)
        printf("%c", arr[p_idx]->data);
      } 
   free(arr);
 }

DC02PE98

判断一条类似链表的结构是否为合法的双向循环链表

【20230831】试写一算法,判断采用双向循环链表定义的、类似链表的结构是否为合法的双向循环链表。在该结构中,data域中记录的字符字符各不相同。

注意:在本道题目中,会打印该结构中所有有关联的DuLNode结点的data值,但由于条件限制,不会打印这些结点的前驱和后继关系。因此需要通过单步调试,观察该结构的任意结点的前驱和后继情况。

// 双向循环链表的类型定义为:
typedef char  ElemType;

typedef struct DuLNode {     
  ElemType  data;  
  struct DuLNode  *prior, *next;  //分别指向直接前驱和直接后继
} DuLNode, *DuLinkList; // 双向链表

typedef DuLinkList DuCirLinkList;  //双向循环链表

实现下列函数:
Status isLeagalDuCirLinkList(DuCirLinkList L)
//如果L是双向循环链表,则返回TRUE;否则返回FALSE。当程序返回TRUE时,系统会打印“合法”,否则会打印“不合法”。

Status isLeagalDuCirLinkList(DuCirLinkList L){
    if (L == NULL) {
        return TRUE;
   }
    DuLNode *current = L;
    DuLNode *visited[256] = {0}; // 用于检查data唯一性(假设ASCII字符)
    int count = 0;    // 检查链表是否循环且节点关系正确
    do {
        // 检查当前节点是否已被访问(防止无限循环)
        if (current == NULL) {
            return false;
        }
      // 检查data唯一性
        if (visited[(unsigned char)current->data] != NULL) {
            return false;
        }
        visited[(unsigned char)current->data] = current;
        if (current->next == NULL || current->prior == NULL) {
            return false;
        }
        if (current->next->prior != current || current->prior->next != current) {            
            return false;
        }
        current = current->next;
        count++;
        if (count > 1000) {
            return false;
        }
    } while (current != L); // 循环回到起点
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值