1.假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的入队列和出队列的算法。
void EnQueue(linkList ﹡rear, int x)//rear是循环链表的尾指针,该操作有点类似链表操作中的尾插法建表
{
s = (LinkList*)malloc(sizeof(Linklist)); //申请结点空间
s->data = x;
s->next = rear->next;//将s结点链入队尾
rear->next = s;
rear = s; //rear指向新队尾
}
int DeQueue(linkList ﹡rear)//出队操作
{
int temp;
if (rear->next == rear)//循环链表、判断队空的条件
{
printf(“队空\n”);
return NULL;
}
s = rear->next->next; //s指向队头元素,
rear->next->next = s->next; //队头元素出队
temp = s->data;//将原队头元素的值存在变量temp中
if (s == rear) rear = rear->next; //空队列
free(s);
return temp;//函数返回值为原来的队头元素
}
2.假设以数组sequ[m]存放循环队列的元素,同时设变量rear和quelen分别指示循环队列中队尾元素的位置和内含元素的个数。试给出判别此循环队列的队满条件,并写出相应的入队列和出队列的算法(在出队的算法中要返回队头元素)。
#define M 128
typedef int datatype;
typedef struct queue
{
datatype sequ[M];
int quelen;//队列的长度
int rear;//指向队尾元素的位置
}sequeue;
int ENQUEUE(sequeue* q, datatype x)//入队的算法
{
if (q->quelen == M)/*判断队列已满的标志*/ return 0;
q->rear = (q->rear + 1) % M;//队尾位置后移
q->sequ[q->rear] = x;//新的队尾元素值为x
q->quelen++;//队列的当前长度+1
return 1;
}
int DEQUEUE(sequeue* q)
{
int pr;
datatype x;
if (q->quelen == 0) return 0;//队列中没有元素可删
pr = (q->rear - q->quelen + 1 + M) % M;//指向队头位置
x = q->sequ[pr];//用变量x存储原队头元素
q->quelen--;//队列长度-1
return x;//函数返回队头元素
}
3.若s一个采用顺序结构存储的串,编写一个函数,要求从s中删除从第i个字符开始的,长度为j的一个子串。
seqstring* Delij(seqstring* s, int i, int j)
{
int h;
if (i + j - 1 <= s->len)
{
for (h = i + j - 1; h <= s->len - 1; h++)
s->ch[h - j] = s->ch[h];
s->len = s->len - j;//更改串的长度
s->ch[s->len] = '\0';
return s;
}
else printf("无法进行删除操作\n");
}
4.若x是采用单链表存储的串,编写一个函数将其中的所有字符c替换成s字符
typedef struct node
{
char data;
struct linknode* next;
} linkstring;
linkstring* trans(linkstring* s, char c1, char c2)
{
linkstring* p;
p = s->next;
while (p != NULL)
{
if (p->data == c1) p->data = c2;
p = p->next;
}
return s;
}