算法模板梳理1--全国大学生算法设计与编程挑战赛(秋季赛)

1.另类的循环队列:

如果用一个循环数组表示队列,并且只设队列头指针Front,不设尾指针Rear,而是另设Count记

队列中元素个数。请编写算法实现队列的入队和出队操作。

bool AddQ(Queue Q,ElementType X) {
    if(Q->Count == Q->MaxSize) {
        printf("Queue Full\n");
        return false;
    }
        Q->Count += 1;
        Q->Data[(Q->Count + Q->Front) % Q->MaxSize] = X;
        return true;
}

ElementType DeleteQ(Queue Q) {
    if(Q->Count == 0) {
        printf("Queue Empty\n");
        return ERROR;
    }
    Q->Front = (Q->Front + 1) % Q->MaxSize;
    Q->Count--;
    return Q->Data[Q->Front];
}

2. 双端队列:

双端队列(deque,即double-ended queue的缩写)是一种具有队列和栈性质的数据结构,即可以(也只能)在线性表的两端进行插入和删除。若以顺序存储方式实现双端队列,请编写例程实现下列操作:

  • Push(X,D):将元素X插入到双端队列D的头;
  • Pop(D):删除双端队列D的头元素,并返回;
  • Inject(X,D):将元素X插入到双端队列D的尾部;
  • Eject(D):删除双端队列D的尾部元素,并返回;
  • //双端队列的实现
    //在队首插入元素
    bool Push(ElementType X,Deque D) {
        if((D->Front - D->Rear + D->MaxSize) % D->MaxSize == 1) {
            return false;
        }
        D->Front = (D->Front - 1 + D->MaxSize) % D->MaxSize;
        D->Data[D->Front] = X;
        return true;
    }
    //在队首删除元素
    ElementType Pop(Deque D) {
        int num;
        if(D->Front == D->Rear) {
            return ERROR;
        }
        num = D->Data[D->Front];
        D->Front = (D->Front + 1) % D->MaxSize;
        return num;
    }
    //在队尾插入元素
    bool Inject(ElementType X,Deque D) {
        if((D->Front - D->Rear + D->MaxSize) % D->MaxSize == 1) {
            return false;
        }
        D->Data[D->Rear] = X;
        D->Rear = (D->Rear + 1) % D->MaxSize;
        return true;
    }
    //在队尾删除元素
    ElementType Eject(Deque D) {
        int num;
        if(D->Front == D->Rear) {
            return ERROR;
        }
        num = D->Data[(D->Rear - 1 + D->MaxSize) % D->MaxSize];
        D->Rear = (D->Rear - 1 + D->MaxSize) % D->MaxSize; 
        return num;
    }

    3.另类堆栈

  • 在栈的顺序存储实现中,另有一种方法是将Top定义为栈顶的上一个位置。请编写程序实现这种定义下堆栈的入栈、出栈操作。如何判断堆栈为空或者满?

  • bool Push(Stack S,ElementType X) {
        if(S->Top == S->MaxSize) {
            printf("Stack Full\n");
            return  false;
        }
        S->Data[S->Top] = X;
        S->Top++;
        return true;
    }
    
    ElementType Pop(Stack S) {
        int num;
        if(S->Top == 0) {
            printf("Stack Empty\n");
            return ERROR;
        }
        S->Top--;
        num = S->Data[S->Top];
        return num;
    }

    4.线性表元素的区间删除

  • 给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素。删除后表中剩余元素保持顺序存储,并且相对位置不能改变。

  • List Delete(List L,ElementType minD,ElementType maxD) {
        int count = 0;
        int i = 0;
        for(i = 0;i <= L->Last;i++) {
            if(L->Data[i] > minD && L->Data[i] < maxD) {
                count++;
            }
            else {
                L->Data[i - count] = L->Data[i];
            }
        }
        L->Last = L->Last - count;
        return L;
    }

    5.输入字符串

  • C语言标准函数库中 scanf 函数和 gets 函数都可以输入字符串,但是各有优、缺点。我们综合两者的优点,克服两者的缺点,设计一个函数来输入字符串。

  • //字符串与输入字符串
    char *GetStr(char *str,int size) {
        int i = 0;
        char c;
        while(c = getchar(),c != '\n'&&i < size - 1) {
            str[i] = c;
            i++;
        }
        str[i] = '\0';
        if(c != '\n') {
            ungetc(c,stdin);
        }
        return str;
    }

    6.求二叉树的高度

  • //使用递归的方法求解二叉树的高度
    int GetHeight(BinTree BT) {
        //用来记录当前左子树的高度
        int lt;
        //用来记录当前右子树的高度
        int rt;
        if(BT == NULL) {
            return 0;
        }
        else {
            lt = GetHeight(BT->Left);
            rt = GetHeight(BT->Right);
            int result;
            if(lt > rt) {
                result = lt;
            }
            else {
                result = rt;
            }
            return result + 1;
        }
    }

    7.二叉树的遍历

  • //二叉树的遍历
    //中序遍历
    void InorderTraversal(BinTree BT) {
        if(BT) {
            InorderTraversal(BT->Left);
            printf(" %c",BT->Data);
            InorderTraversal(BT->Right);
        }
    }
    //前序遍历
    void PreorderTraversal(BinTree BT) {
        if(BT) {
            printf(" %c",BT->Data);
            PreorderTraversal(BT->Left);
            PreorderTraversal(BT->Right);
        }
    }
    //后序遍历
    void PostorderTraversal(BinTree BT) {
        if(BT) {
            PostorderTraversal(BT->Left);
            PostorderTraversal(BT->Right);
            printf(" %c",BT->Data);
        }
    }
    //层次遍历
    void LevelorderTraversal(BinTree BT) {
        BinTree q[100],p;
        int front = 0,rear = 0;
        if(!BT) return;
        else {
            q[rear++] = BT;
            while(front != rear) {
                p = q[front++];
                printf(" %c",p->Data);
                if(p->Left) q[rear++] = p->Left;
                if(p->Right) q[rear++] = p->Right;
            }
        }
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值