《数据结构与算法分析C++描述》课后习题3.28、3.30

是两个手写数据结构的题,所以想着记录一下,说不定以后哪天就用上了(可能不会)

另外3.30的第三问怎么证明啊,有无会的大佬教一下,呜呜。

3.28 实现双端队列

/* 本双端队列中:
1.[head,rear-1]范围内存元素
2.特殊地,head==rear时为空,head==(rear+1)%size时为满
3.为了满足2的要求,数组中留空一个位置,size大小的数组只能存size-1个元素
*/
template<class T>
class Deque{
private:
    vector<T> dq;
    int head, rear, size;

public:
    Deque(int n){
        size=n+1;
        head=rear=0;
        dq=vector<T>(n+1);
    }
    bool isFull(){ //检查是否为满
        return head==(rear+1)%size;
    }
    bool isEmpty(){ //检查是否为空
        return head==rear;
    }
    bool push(T x){ //插入前端
        if(isFull()) return false; //已满,添加失败
        head = (head-1+size)%size;
        dq[head]=x;
        return true;
    }
    T pop(){ //删除前端并返回
        if(isEmpty()) return -1; //已空,删除失败
        int pre=head;
        head = (head+1)%size;
        return dq[pre];
    }
    bool inject(T x){ //插入后端
        if(isFull()) return false;
        dq[rear]=x;
        rear=(rear+1)%size;
        return true;
    }
    bool eject(){ //删除后端并返回
        if(isEmpty()) return -1;
        rear=(rear-1+size)%size;
        return dq[rear];
    }
};

3.30 实现自调整表(数组实现+链表实现)

/* 基于数组实现的自调整表
1.[0,cnt-1]范围内存储元素
2.插入操作和find操作都是O(N)的复杂度
*/
template<class T>
class Self_Adjust_List{
private:
    vector<T> sal;
    int size, cnt;

public:
    Self_Adjust_List(int n){
        sal=vector<T>(n);
        size=n, cnt=0;
    }
    bool isFull(){
        return cnt==size;
    }
    bool isEmpty(){
        return cnt==0;
    }
    bool insert(T x){
        if(isFull()) return false; //满了,插入失败
        for(int i=cnt-1; i>=0; i--){
            sal[i+1]=sal[i];
        }
        sal[0]=x, cnt++;
        return true;
    }
    bool find(T x){
        int pos=-1;
        for(int i=0; i<=cnt-1; i++){
            if(sal[i]==x) {pos=i; break;}
        }
        if(pos==-1) return false; //没找到元素x
        for(int i=pos-1; i>=0; i--){
            sal[i+1]=sal[i];
        }
        sal[0]=x;
        return true;
    }
    void printTop(){
        cout<<sal[0]<<endl;
    }
};

/* 链表结点的结构体实现(用来实现后面的自调整表的链表实现)
使用方法:node<int> *head = new node<int>(); head->val=1;
*/
template <class T>
struct node{
    node* nxt;
    T val;
    node(){nxt=nullptr; val=0;}
    node(T x){nxt=nullptr; val=x;}
};

/* 自调整表的链表实现
1.由于是链表实现,不再设空间限制
2.插入操作是O(1),find操作是O(N)
3.但如果每个元素都有固定的访问概率pi,那么访问概率高的将更容易排在表的前面,
这使得find操作的均摊复杂度要优于线性复杂度
4.上述分析的证明我也不会,呜呜
*/
template <class T>
class Self_Adjust_List2{
private:
    int size;
    node<T> *head;

public:
    Self_Adjust_List2(){
        size=0;
        head = new node<T>();
    }

    //以下是两个实现所需的链表函数
    void addAtHead(T x){ //把元素加到链表头
        node<T> *cur = new node<T>(x);
        cur->nxt = head->nxt;
        head->nxt = cur;
        size++;
    }
    void deleteNext(node<T> *cur){ //把当前指针的nxt指向的元素删掉
        node<T> *toDel = cur->nxt; //将要删掉的元素的指针
        if(toDel==nullptr) return; //如果是空的,就不用删了
        cur->nxt = toDel->nxt;
        delete toDel;
        size--;
    }

    //以下是两个自调整表的函数
    void insert(T x){
        addAtHead(x);
    }
    bool find(T x){
        node<T> *cur=head; //设置一个指针从head开始遍历链表
        for(; ; cur=cur->nxt){ //遍历链表
            if(cur->nxt==nullptr) return false; //没找到元素x
            if(cur->nxt->val==x) break; //找到目标元素,进入下一步
        }
        //删除然后在前端加,相当于移到前端
        deleteNext(cur);
        addAtHead(x);
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值