3,假设以1和0分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由1和0组成的序列,可以操作的序列称为合法序列,否则称为非法序列。写出一个算法,判定所给的操作序列是否合法。若合法,返回true,否则返回false (假定被判定的操作序列已存入一维数组中).

int Judge(char A[]) {
    int i = 0;
    int j = k = 0;
    while (A[i] != '\0') {
        switch (A[i]) {
        case 'I':j++; break;
        case 'O':k++;
            if (k > j) { printf("序列非法\n"); exit(0); }
        }
        i++;
    }
    if (j != k) {
        printf("序列非法\n");
        return false;
    }
    else {
        printf("序列合法\n");
        return true;
    }
}

4.设单链表的表头指针为L, 结点结构由data和next两个城构成, 其中data域为字符型。试设计算
法判断该链表的全部n个字符是否中心对称。例如xyx, xyyx都是中心对称。

int dc(LinkList L, int n) {
    int i;
    char s[n / 2];
    p = L->next;
    for (i = 0; i < n / 2; i++) {
        s[i] = p->data;
        p = p->next;
    }
    i--;   //注意此处减一操作
    if (n % 2 == 1)
        p = p->next;
    while (p != NULL && s[i] == p->data) {
        i--;
        p = p->next;
    }
    if (i == 1)
        return 1;
    else
        return 0;
}

5.设有两个栈s1、s2都采用顺序栈方式, 并共享一个存储区[0, . maxsize - 1], 为了尽量利用
空间, 减少溢出的可能, 可采用栈顶相向、迎面增长的存储方式。试设计s1s2有关入栈和出栈的
操作算法。

typedef struct {
    elemtp stack[maxsize];
    int top[2];
}stk;
stk s;

int push(int i, elemtp x) {
    //i为栈号, i = 0表示左边的s1栈, i = 1表示右边的s2栈, x是入栈元素//入栈成功返回1,否则返回0
    if (i < 0 || i>1) {
        printf("栈号不对");
        exit(0);
    }
    if (s.top[1] - s.top[0] == 1) {
        printf("栈已满");
        return 0;
    }
    switch (i) {
    case 0:s.stack[++s.top[0]] = x; return 1; break;
    case 1:s.stack[--s.top[1]] = x; return 1;
    }
}


elemtp pop(int i) {
    if (i < 0 || i>1) {
        printf("栈号输入错误");
        exit(0);
    }
    switch (i) {
    case 0:
        if (s.top[0] == -1) {
            printf("栈空");
            return -1;
        }
        else {
            return s.stack[s.top[0]--];
        }
    case 1:
        if (s.top[1] == maxsize) {
            printf("栈空");
            return -1;
        }
        else {
            return s.stack[s.top[1]++];
        }
    }
}

 6.若希望循环队列中的元素都能得到利用, 则需设置一个标志域tag, 并以tag的值为0或1来区分队头指针front和队尾指针rear相同时的队列状态是“空”还是“满”。试编写与此结构相应的入队和出队算法。

int Enueue1(Squeue& Q, ElemType x) {
    if (Q.front == Q.rear && Q.tag == 1)
        return 0;      //队满
    Q.data[Q.rear] = x;
    Q.rear = (Q.rear + 1) % MaxSize;
    Q.tag = 1;
    return 1;
}

int DeQueue1(Squeue& Q, ElemType& x) {
    if (Q.front == Q.rear && Q.tag == 0)
        retunr 0;      //队空
    x = Q.data[Q.front];
    Q.front = (Q.front + 1) % MaxSize;
    Q.tag = 0;
    return 1;
}

7.Q是一个队列,S是一个空栈,实现将队列中的元素逆置的算法

void Inverse(Stack S, Queue Q) {
    while (!QueueEmpty(Q)) {
        x = DeQueue(Q);
        Push(S, x);
    }
    while (!StackEmpty(S)) {
        Pop(S, x);
        EnQueue(Q, x);
    }
}

8.利用两个栈S1,S2来模拟一个队列。

//入队算法
int EnQueue(Stack& S1, Stack& S2, ElemType e) {
    if (!StackOverflow(S1)) {
        Push(S1, e);
        return 1;
    }
    if (StackOverflow(S1) && !StackEmpty(S2)) {
        cout << "队列满" << endl;
        return 0;
    }
    if (StackOverflow(S1) && StackEmpty(S2)) {
        while (!StackEmpty(S1)) {
            Pop(S1, x);
            Push(S2, x);
        }
    }
    Push(S1, e);
    return 1;
}
//出队算法
void DeQueue(Stack& S1, Stack& S2, ElemType& x) {
    if (!StackEmpty(S2)) {
        Pop(S2, x);
    }
    else if (StackEmpty(S1)) {
        cout << "队列为空" << endl;
    }
    else {
        while (!StackEmpty(S1)) {
            Pop(S1, x);
            Push(S2, x);
        }
        Pop(S2, x);
    }
}

//判断队列为空的算法
int QueueEmpty(Stack S1, Stack S2) {
    if (StackEmpty(S1) && StackEmpty(S2))
        return 1;
    else:
        return 0;
}

 

posted @ 2021-08-14 15:13  为红颜  阅读(395)  评论(0编辑  收藏  举报