目录
自己乱写的代码,希望有大佬指导一下~
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 5typedef 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 5typedef 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;
}
2012

被折叠的 条评论
为什么被折叠?



