广工 AnyviewC 数据结构习题 第二章
- 广工 AnyviewC 数据结构习题 第二章
- Anyview 数据结构 第二章
- 1【题目】试写一算法,实现顺序栈的判空操作
- 2【题目】试写一算法,实现顺序栈的取栈顶元素操作
- 3【题目】试写一算法,实现顺序栈的出栈操作
- 4 【题目】若顺序栈的类型重新定义如下。试编写算法,
- 5【题目】若顺序栈的类型重新定义如下。试编写算法,
- 6【题目】若顺序栈的类型重新定义如下。试编写算法,
- 7 【题目】若顺序栈的类型重新定义如下。试编写算法,
- 8【题目】试写一算法,借助辅助栈,复制顺序栈S1得到S2。
- 9【题目】试写一算法,求循环队列的长度。
- 10【题目】如果希望循环队列中的元素都能得到利用,
- 11【题目】假设将循环队列定义为:以域变量rear
- 12【题目】已知k阶斐波那契序列的定义为:
- 12【题目】设A=(a1,…,am)和B=(b1,…,bn)均为有序顺序表,
- 13 【题目】试写一算法,实现顺序表的就地逆置,
- 14【题目】试对一元稀疏多项式Pn(x)采用存储量同多项式
- 15 【题目】假设有两个集合A和B分别用两个线性表LA和LB
- 16【题目】试写一算法,实现链栈的判空操作。
- 17 【题目】试写一算法,实现链栈的取栈顶元素操作。
- 18 【题目】试写一算法,实现链队列的判空操作。
- 19 【题目】试写一算法,实现链队列的求队列长度操作。
- 20【题目】(PE68) 假设以带头结点的循环链表表示队列,并且
- 21 【题目】试写一算法,实现带头结点单链表的判空操作。
- 22 【题目】试写一算法,实现带头结点单链表的销毁操作。
- 23 【题目】试写一算法,实现带头结点单链表的清空操作。
- 24 【题目】试写一算法,实现带头结点单链表的求表长度操作。
- 25(PE82)【题目】试写一算法,在带头结点单链表L插入第i元素e。
- 26(84)【题目】试写一算法,在带头结点单链表删除第i元素到e。
- 27 【题目】试写一算法,在带头结点单链表的第i元素起的
- 28【题目】试写一算法,在带头结点单链表删除第i元素
- 29【题目】试写一算法,删除带头结点单链表中所有值
- 30【题目】试写一算法,删除带头结点单链表中所有值
广工 AnyviewC 数据结构习题 第二章
Anyview 数据结构 第二章
/**********
1【题目】试写一算法,实现顺序栈的判空操作
StackEmpty_Sq(SqStack S)。
顺序栈的类型定义为:
typedef struct {
ElemType *elem; // 存储空间的基址
int top; // 栈顶元素的下一个位置,简称栈顶位标
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack; // 顺序栈
***********/
Status StackEmpty_Sq(SqStack S)
/* 对顺序栈S判空。 */
/* 若S是空栈,则返回TRUE;否则返回FALSE */
{
if ( S.top == 0)
return TRUE;
return FALSE;
}
/**********
2【题目】试写一算法,实现顺序栈的取栈顶元素操作
GetTop_Sq(SqStack S, ElemType &e)。
顺序栈的类型定义为:
typedef struct {
ElemType *elem; // 存储空间的基址
int top; // 栈顶元素的下一个位置,简称栈顶位标
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack; // 顺序栈
***********/
Status GetTop_Sq(SqStack S, ElemType &e)
/* 取顺序栈S的栈顶元素到e,并返回OK; */
/* 若失败,则返回ERROR。 */
{
if (S.top==0)
return ERROR;
e = S.elem[S.top-1];
return OK;
}
/**********
3【题目】试写一算法,实现顺序栈的出栈操作
Pop_Sq(SqStack &S, ElemType &e)。
顺序栈的类型定义为:
typedef struct {
ElemType *elem; // 存储空间的基址
int top; // 栈顶元素的下一个位置,简称栈顶位标
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack; // 顺序栈
***********/
Status Pop_Sq(SqStack &S, ElemType &e)
/* 顺序栈S的栈顶元素出栈到e,并返回OK;*/
/* 若失败,则返回ERROR。 */
{
if (S.top==0)
return ERROR;
e = S.elem[S.top-1];
S.top-=1;
return OK;
}
/**********
4 【题目】若顺序栈的类型重新定义如下。试编写算法,
构建初始容量和扩容增量分别为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。 */
{
if (size>0 && inc>0)
{
S.size=size;
S.increment=inc;
S.top=size;
return OK;
}
return ERROR;
}
/**********
5【题目】若顺序栈的类型重新定义如下。试编写算法,
实现顺序栈的判空操作。
typedef struct {
ElemType *elem; // 存储空间的基址
ElemType *top; // 栈顶元素的下一个位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack2;
***********/
Status StackEmpty_Sq2(SqStack2 S)
/* 对顺序栈S判空。 */
/* 若S是空栈,则返回TRUE;否则返回FALSE */
{
if (S.top==S.elem)
return TRUE;
return FALSE;
}
/**********
6【题目】若顺序栈的类型重新定义如下。试编写算法,
实现顺序栈的入栈操作。
typedef struct {
ElemType *elem; // 存储空间的基址
ElemType *top; // 栈顶元素的下一个位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack2;
***********/
Status Push_Sq2(SqStack2 &S, ElemType e)
/* 若顺序栈S是满的,则扩容,若失败则返回ERROR。*/
/* 将e压入S,返回OK。 */
{
if (S.top>=S.elem+S.size)
{
if (S.increment<=0)
return ERROR;
ElemType *p;
p = (ElemType *) realloc (S.elem,(S.size+S.increment)*sizeof(ElemType));
if (p==NULL)
return ERROR;
S.elem=p;
S.top=S.elem+S.size;
S.size+=S.increment;
}
*S.top=e;
S.top++;
return OK;
}
/**********
7 【题目】若顺序栈的类型重新定义如下。试编写算法,
实现顺序栈的出栈操作。
typedef struct {
ElemType *elem; // 存储空间的基址
ElemType *top; // 栈顶元素的下一个位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack2;
***********/
Status Pop_Sq2(SqStack2 &S, ElemType &e)
/* 若顺序栈S是空的,则返回ERROR; */
/* 否则将S的栈顶元素出栈到e,返回OK。*/
{
if (S.top==S.elem)
return ERROR;
e = *(S.top-1);
S.top-=1;
return OK;
}
/**********
8【题目】试写一算法,借助辅助栈,复制顺序栈S1得到S2。
顺序栈的类型定义为:
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)
/* 借助辅助栈,复制顺序栈S1得到S2。 */
/* 若复制成功,则返回TRUE;否则FALSE。 */
{
ElemType e;
SqStack S0;
InitStack_Sq(S0, S1.size, S1.increment);
InitStack_Sq(S2, S1.size, S1.increment);
S0.top=0;
S2.top=0;
if (StackEmpty_Sq(S1)==TRUE )
{
return TRUE;
}
int i,l;
l=S1.top;
for (i=0;i<l;i++)
{
Pop_Sq(S1, e);
Push_Sq(S0, e);
}
for (i=0;i<l;i++)
{
Pop_Sq(S0, e);
Push_Sq(S2,e);
}
DestroyStack_Sq(S0);
return OK;
}
/**********
9【题目】试写一算法,求循环队列的长度。
循环队列的类型定义为:
typedef struct {
ElemType *base; // 存储空间的基址
int front; // 队头位标
int rear; // 队尾位标,指示队尾元素的下一位置
int maxSize; // 最大长度
} SqQueue;
***********/
int QueueLength_Sq(SqQueue Q)
/* 返回队列Q中元素个数,即队列的长度。 */
{
int l = (Q.rear - Q.front + Q.maxSize) % Q.maxSize ;
return l;
}
/**********
10【题目】如果希望循环队列中的元素都能得到利用,
则可设置一个标志域tag,并以tag值为0或1来区分尾
指针和头指针值相同时的队列状态是"空"还是"满"。
试编写与此结构相应的入队列和出队列的算法。
本题的循环队列CTagQueue的类型定义如下:
typedef struct {
ElemType elem[MAXQSIZE];
int tag;
int front;
int rear;
} CTagQueue;
**********/
Status EnCQueue(CTagQueue &Q, ElemType x)
/* 将元素x加入队列Q,并返回OK;*/
/* 若失败,则返回ERROR。 */
{
if (Q.tag == 1 && Q.front==Q.rear)
return ERROR;
Q.elem[Q.rear]=x;
Q.rear=(Q.rear+1) % MAXQSIZE;
return OK;
}
Status DeCQueue(CTagQueue &Q, ElemType &x)
/* 将队列Q的队头元素退队到x,并返回OK;*/
/* 若失败,则返回ERROR。 */
{
if (Q.tag == 0 && Q.front==Q.rear)
return ERROR;
x=Q.elem[Q.front];
Q.front=(Q.front+1) % MAXQSIZE;
return OK;
}
/**********
11【题目】假设将循环队列定义为:以域变量rear
和length分别指示循环队列中队尾元素的位置和内
含元素的个数。试给出此循环队列的队满条件,并
写出相应的入队列和出队列的算法(在出队列的算
法中要返回队头元素)。
本题的循环队列CLenQueue的类型定义如下:
typedef struct {
ElemType elem[MAXQSIZE];
int length;
int rear;
} CLenQueue;
**********/
Status EnCQueue(CLenQueue &Q, ElemType x)
/* 将元素x加入队列Q,并返回OK;*/
/* 若失败,则返回ERROR。 */
{
if (Q.elem==NULL || 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)
/* 将队列Q的队头元素退队到x,并返回OK;*/
/* 若失败,则返回ERROR。 */
{
if (Q.elem==NULL ||Q.length==0)
return ERROR;
if(Q.rear+1>=Q.length)
x=Q.elem[Q.rear+1-Q.length];
else
x=Q.elem[MAXQSIZE-Q.length+Q.rear+1];
//x = Q.elem[(Q.length-Q,rear + MAXQSIZE) % MAXQSIZE];
--Q.length;
return OK;
}
12【题目】已知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项fn
要求:必须使用循环队列
*/
{
long sum = 0;
int i, j,m;
SqQueue a;
a.maxSize = k+1;
//注意循环队列由于判空判满的问题所以有一个元素空间没有用
a.base = (ElemType*)malloc(a.maxSize * sizeof(ElemType));
a.front = 0;
a.rear = 0;
if (n < k - 1)
{
sum = 0;
return sum;
}
else if (n == k-1)
{
sum = 1;
return sum;
}
//初始化该队列对应的斐波那契数列
do
{
a.base[a.rear] = 0;
a.rear = (a.rear + 1) % a.maxSize;
} while ((a.rear + 1) % a.maxSize != a.front);
a.base[a.rear-1] = 1;
cout << a.base[a.rear-1] << endl;
cout << a.rear << endl;
cout << a.front << endl;
cout << endl;
m = a.front;
for (i = k-1; i < n; i++)
{
long v = 0;
j = a.front;
do
{
v += a.base[j];
cout << "v:" << v << " " << "j:" << j << endl;
j = (j + 1) % a.maxSize;
} while ((j + 1) % a.maxSize != a.front);
cout << endl;
cout << "v:" << v << " "<< "i:" << i << endl;
cout << "rear " << a.rear << endl;
cout << endl;
a.base[a.rear] = v;
if ((a.rear + 1) % a.maxSize == a.front)
{
a.rear = a.front;
}
else
a.rear = (a.rear + 1) % a.maxSize;
a.front = (a.front + 1) % a.maxSize;
}
sum = 0;
j = a.front;
do
{
sum += a.base[j];
cout << a.base[j] << " " << "j:" << j << endl;
j = (j + 1) % a.maxSize;
} while ((j + 1) % a.maxSize != a.front);
return sum;
}
/**********
12【题目】设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 */
{
int i;
if (A.elem[0]!=B.elem[0])
{
if (A.elem[0] < B.elem[0])
return '<';
else if (A.elem[0] > B.elem[0] )
return '>';
else if (A.length == B.length)
return '=';
}
for (i=0;i<A.length;i++)
{
if (A.elem[i] == B.elem[i])
continue;
else
break;
}
if (i == A.length)
{
if (i == B.length)
return '=';
else
return '<';
}
else
{
if (i+1 == B.length)
return '>';
else if (A.length < B.length)
return '<';
else if (A.length > B.length)
return '>';
else if (A.elem[i+1] < B.elem[i+1])
return '<';
else
return '>';
}
}
/**********
13 【题目】试写一算法,实现顺序表的就地逆置,
即利用原表的存储空间将线性表(a1,a2,…,an)
逆置为(an,an-1,…,a1)。
顺序表类型定义如下:
typedef struct {
ElemType *elem;
int length;
int size;
int increment;
} SqList;
**********/
void Inverse(SqList &L)
{
for (i=0;i<L.length/2;i++)
{
ElemType t;
t = L.elem[i];
L.elem[i] = L.elem[L.length - i - 1];
L.elem[L.length - i - 1] = t;
}
}
/**********
14【题目】试对一元稀疏多项式Pn(x)采用存储量同多项式
项数m成正比的顺序存储结构,编写求Pn(x0)的算法(x0
为给定值)。
一元稀疏多项式的顺序存储结构:
typedef struct {
int coef; // 系数
int exp; // 指数
} Term;
typedef struct {
Term *elem; // 存储空间基址
int length; // 长度(项数)
} Poly;
**********/
float Evaluate(Poly P, float x)
/* P.elem[i].coef 存放ai, */
/* P.elem[i].exp存放ei (i=1,2,...,m) */
/* 本算法计算并返回多项式的值。不判别溢出。 */
/* 入口时要求0≤e1<e2<...<em,算法内不对此再作验证 */
{
int i, j;
float sum = 0;
float t;
for ( i = 0; i < P.length; i++)
{
t = x;
if (P.elem[i].exp == 0)
{
t = 1.0;
}
else
{
for ( j = 1; j < P.elem[i].exp; j++)
t *= x;
}
sum += (float)P.elem[i].coef*t;
}
return sum;
}
/**********
15 【题目】假设有两个集合A和B分别用两个线性表LA和LB
表示(即:线性表中的数据元素即为集合中的成员),
试写一算法,求并集
A
=
A
∪
B
A=A∪B
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, SqList Lb)
{
if (La.elem == NULL)
if (Lb.elem == NULL)
La.elem == NULL;
else
La.elem = Lb.elem;
else
{
int la = ListLength_Sq(La);
int lb = ListLength_Sq(Lb);
int i,j;
for (i = 1;i <= lb;i++)
{
GetElem_Sq(Lb,i,j);
if (Search_Sq(La,j) != -1)
continue;
else
{
//if (La.length+1 == La.size)
Append_Sq(La,j);
}
}
}
}
求出并集,要放到第一个表里!!
/**********
16【题目】试写一算法,实现链栈的判空操作。
链栈的类型定义为:
typedef struct LSNode {
ElemType data; // 数据域
struct LSNode *next; // 指针域
} LSNode, *LStack; // 结点和链栈类型
***********/
Status StackEmpty_L(LStack S)
/* 对链栈S判空。若S是空栈,则返回TRUE;否则返回FALSE */
{
if (S == NULL)
return TRUE;
else
return FALSE;
}
/**********
17 【题目】试写一算法,实现链栈的取栈顶元素操作。
链栈的类型定义为:
typedef struct LSNode {
ElemType data; // 数据域
struct LSNode *next; // 指针域
} LSNode, *LStack; // 结点和链栈类型
***********/
Status GetTop_L(LStack S, ElemType &e)
/* 取链栈S的栈顶元素到e,并返回OK; */
/* 若S是空栈,则失败,返回ERROR。 */
{
if (S == NULL)
return ERROR;
else
{
e = S->deta;
return OK;
}
}
/**********
18 【题目】试写一算法,实现链队列的判空操作。
链队列的类型定义为:
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。*/
{
if (Q.front->next == Q.rear)
return TRUE;
else
return FALSE;
}
/**********
19 【题目】试写一算法,实现链队列的求队列长度操作。
链队列的类型定义为:
typedef struct LQNode {
ElemType data;
struct LQNode *next;
} LQNode, *QueuePtr; // 结点和结点指针类型
typedef struct {
QueuePtr front; // 队头指针
QueuePtr rear; // 队尾指针
} LQueue; // 链队列类型
***********/
int QueueLength_LQ(LQueue Q)
/* 求链队列Q的长度并返回其值 */
{
int l = 0;
QueuePtr p = Q.front;
while(p->next != Q.rear)
{
l++;
p = p->next;
}
return l;
}
/**********
20【题目】(PE68) 假设以带头结点的循环链表表示队列,并且
只设一个指针指向队尾元素结点(注意不设头指针),
试编写相应的队列初始化、入队列和出队列的算法。
带头结点循环链队列CLQueue的类型定义为:
typedef struct LQNode {
ElemType data;
struct LQNode *next;
} LQNode, *CLQueue;
**********/
Status InitCLQueue(CLQueue &rear) // 初始化空队列
{
if (NULL == (rear = (CLQueue) malloc (sizeof(CLQueue))))
return OVERFLOW;
else
{
rear->next = NULL;
//L->next = rear;
return OK;
}
}
Status EnCLQueue(CLQueue &rear, ElemType x) // 入队
{
CLQueue p;
//q = rear->next;
if (NULL == (p = (LQNode*) malloc (sizeof(LQNode))))
return OVERFLOW;
p->data = x;
//printf("%c\n",x);
//printf("\n");
p->next = rear->next;
rear->next = p;
rear = p;
//rear->next->data;
return OK;
}
Status DeCLQueue(CLQueue &rear, ElemType &x) // 出队
{
CLQueue p = rear;
if (rear->next == NULL)
return ERROR;
else
{
while (p->next != rear)
p = p->next;
x = rear->data;
rear = rear->next;
p->next = rear;
return OK;
}
}
注意:
在使用malloc函数来分派内存的时候,前面括号里是该类型的指针类型,后面括号才是该类型
(隔了一段时间就容易忘……2333……)
在自己电脑的测试代码及数据
#include <iostream>
#include <cstdlib>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
#define ElemType char
typedef struct LQNode {
ElemType data;
struct LQNode *next;
} LQNode, *CLQueue;
Status InitCLQueue(CLQueue &rear) // 初始化空队列
{
if (NULL == (rear = (CLQueue)malloc(sizeof(CLQueue))))
return OVERFLOW;
else
{
rear->next = rear;
//L->next = rear;
return OK;
}
}
Status EnCLQueue(CLQueue &rear, ElemType x) // 入队
{
CLQueue p;
if (NULL == (p = (CLQueue)malloc(sizeof(CLQueue))))
return OVERFLOW;
p->data = x;
p->next = rear->next;
rear->next = p;
rear = p;
return OK;
}
Status DeCLQueue(CLQueue &rear, ElemType &x) // 出队
{
CLQueue p = rear->next;
CLQueue q = p->next;
if (rear->next == rear)
return ERROR;
else
{
x = q->data;
p->next = q->next;
return OK;
}
}
//定义一个打印函数
void printCLquene(CLQueue rear)
{
CLQueue p = rear->next;
p = p->next;
while (p != rear->next)
{
printf("%c",p->data);
p = p->next;
}
cout << endl;
}
//输入函数
void input(CLQueue &rear,int n)
{
char c;
CLQueue q,p;
p = rear->next;
for (int i = 0; i < n; i++)
{
cout << "输入data" << endl;
cin >> c;
q = (CLQueue)malloc(sizeof(CLQueue));
q->data = c;
rear->next = q;
rear = q;
rear->next = p;
}
}
int main()
{
//定义一个循环列表
CLQueue rear, p,q;
初始化
InitCLQueue(rear);
input(rear, 3);
printCLquene(rear);
//入队操作
ElemType e;
e = 'M';
EnCLQueue(rear,e);
printCLquene(rear);
return 0;
}
/**********
21 【题目】试写一算法,实现带头结点单链表的判空操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status ListEmpty_L(LinkList L)
/* 判定带头结点单链表L是否为空链表。 */
/* 若L是空链表,则返回TRUE,否则FALSE。*/
{
if (L->next == NULL)
return TRUE;
else
return FALSE;
}
/**********
22 【题目】试写一算法,实现带头结点单链表的销毁操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status DestroyList_L(LinkList &L)
/* 销毁带头结点单链表L,并返回OK。*/
{
LinkList p,q;
LinkList a,b,c;
p = L->next;
if (p == NULL)
{
free(L);
return OK;
}
while (p != NULL)
{
q = p;
p = p->next;
free(q);
}
free(L);
return OK;
}
/**********
23 【题目】试写一算法,实现带头结点单链表的清空操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status ClearList_L(LinkList &L)
/* 将带头结点单链表L置为空表,并返回OK。*/
/* 若L不是带头结点单链表,则返回ERROR。 */
{
if (NULL == L)
return ERROR;
LinkList p,q;
LinkList a,b,c;
p = L->next;
if (p == NULL)
return OK;
while (p != NULL)
{
q = p;
p = p->next;
free(q);
}
L->next = NULL;
return OK;
}
/**********
24 【题目】试写一算法,实现带头结点单链表的求表长度操作。
单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList; // 结点和结点指针类型
***********/
int ListLength_L(LinkList L)
/* 求带头结点单链表L的长度,并返回长度值。*/
/* 若L不是带头结点单链表,则返回-1。 */
{
if (NULL == L)
return -1;
LinkList p;
p = L->next;
int num = 0;
while (p != NULL)
{
p = p->next;
num++;
}
return num;
}
/**********
25(PE82)【题目】试写一算法,在带头结点单链表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。 */
{
LinkList p = L;
if (NULL == p || i <1)
return ERROR;
int num = 1;
while (p->next != NULL && num<i)
{
p = p->next;
num++;
}
if (num <i)
return ERROR;
LinkList m;
m = (LinkList) malloc (sizeof(LNode));
m->next = p->next;
p->next = m;
m->data = e;
return OK;
}
测试代码
#include <iostream>
#include <cstdlib>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
#define ElemType char
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
Status Insert_L(LinkList L, int i, ElemType e)
/* 在带头结点单链表L插入第i元素e,并返回OK。*/
/* 若参数不合理,则返回ERROR。 */
{
LinkList p = L;
if (NULL == p || i <1)
return ERROR;
int num = 1;
while (p->next != NULL && num<i)
{
p = p->next;
num++;
}
if (num <i)
return ERROR;
LinkList m;
m = (LinkList)malloc(sizeof(LinkList));
m->next = p->next;
p->next = m;
m->data = e;
return OK;
}
//初始化带头结点的单链表函数
void InitLinkList(LinkList &L)
{
LinkList q;
char c[] = {"abcdefg"};
q = L;
//q->next = L->next;
for (int i = 0; i < 7; i++)
{
LinkList p = (LinkList)malloc(sizeof(LinkList));
p->data = c[i];
p->next = q->next;
q->next = p;
q = q->next;
}
//L = q;
}
//定义打印函数
void printLinkLIst(LinkList &L)
{
LinkList p;
p = L->next;
while (p != NULL)
{
cout << p->data;
p = p->next;
}
cout << endl;
}
int main()
{
//定义一个带头结点的单链表
//L3 = ( abcdefg)
LinkList L = (LinkList)malloc(sizeof(LinkList));
L->next = NULL;
InitLinkList(L);
printLinkLIst(L);
Insert_L(L,2,'*');
printLinkLIst(L);
return 0;
}
/**********
26(84)【题目】试写一算法,在带头结点单链表删除第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。 */
{
LinkList p = L;
LinkList q ;
if (NULL == p || i <1)
return ERROR;
int num = 0;
while (p->next != NULL && num<i)
{
q = p;
p = p->next;
num++;
}
if (i > num)
return ERROR;
LinkList m = p;
e = m->data;
q->next = m->next;
//free(m);
return OK;
}
/**********
27 【题目】试写一算法,在带头结点单链表的第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。 */
{
LinkList p = L;
LinkList q;
q = (LinkList) malloc (sizeof(LNode));
Li = (LinkList) malloc (sizeof(LNode));
if (NULL == p || i <1)
{
Li = NULL;
return ERROR;
}
int num = 0;
while (p->next != NULL && num<i)
{
q = p;
p = p->next;
num++;
}
if (i > num)
{
Li = NULL;
return ERROR;
}
LinkList p1 = p;
LinkList p2 = Li;
while (p1 != NULL)
{
q->next = p1->next;
p1->next = p2->next;
p2->next = p1;
p1 = q->next;
p2 = p2->next;
}
return OK;
}
注意!!别忘了出错的时候把Li置为空
/**********
28【题目】试写一算法,在带头结点单链表删除第i元素
起的所有元素。
带头结点单链表的类型定义为:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
**********/
Status Cut_L(LinkList L, int i)
/* 在带头结点单链表L删除第i元素起的所有元素,并返回OK。*/
/* 若参数不合理,则返回ERROR。 */
{
LinkList p = L;
if (NULL == p || i <1)
return ERROR;
int num = 0;
while (p->next != NULL )
{
p = p->next;
num++;
}
if (i > num)
return ERROR;
LinkList m = L;
for(int k=0;k<i-1;k++)
m = m->next;
m->next=null;
return OK;
}
/**********
29【题目】试写一算法,删除带头结点单链表中所有值
为x的元素,并释放被删结点空间。
单链表类型定义如下:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
**********/
Status DeleteX_L(LinkList L, ElemType x)
/* 删除带头结点单链表L中所有值为x的元素, */
/* 并释放被删结点空间,返回实际删除的元素个数。*/
{
LinkList p = L;
if (NULL == p->next)
return ERROR;
int num = 0;
LinkList m;
while (p != NULL)
{
m = p;
if (m->next->data == x)
{
m = m->next;
p->next = m->next;
free(m);
num++;
}
p = p->next;
}
return num;
}
30【题目】试写一算法,删除带头结点单链表中所有值
小于x的元素,并释放被删结点空间。
单链表类型定义如下:
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
******/
Status DeleteSome_L(LinkList L, ElemType x)
/* 删除带头结点单链表L中所有值小于x的元素, */
/* 并释放被删结点空间,返回实际删除的元素个数。*/
{
LinkList p = L;
if (NULL == p->next)
return ERROR;
int num = 0,flag;
LinkList m;
while (p->next != NULL)
{
flag = 0;
if (p->next->data < x)
{
m = p->next;
p->next = m->next;
free(m);
num++;
flag = 1;
}
if (!flag)
p = p->next;
}
return num;
}