zoukankan      html  css  js  c++  java
  • 大一数据结构基础考核

    数据结构基础

    1. 实现一个函数,参数为一个字符串,该字符串中只包含左花括号

    { 和右花括号 } ,如果左右括号是匹配的,那么函数返回 True,
    否则返回 False

    比如,这个字符串是匹配的:{{}}

    还有这样:{}{{}}{}{{}{}}

    但是这样的字符串是不匹配的:{}}}{{}{}{{}}}

    利用数据结构的知识解题。

    - 非常裸的一个栈题
    
    - 把字符串a传入 rev函数中 ,遍历a中的所有元素,
    
        碰到左括号 就push,栈顶指针top++,
        
        碰到 右括号 尝试pop,如果当前栈定没有 左括号
    
        则pop失败,直接返回 0,如果成功pop,栈顶指针向下移动一位 top--
    
        最后判断top == 0 是否成立,如果字符串是完全匹配的,栈为空,top==0
    
        反之,top!=0 栈内还有元素
    
    #include <bits/stdc++.h>
    using namespace std;
    const int N=5e5;
    char a[N],b[N];
    int top=0;
    int rev(char *s){
    	int len=strlen(s);
    	for(int i=0;i<len;++i){
    		if(s[i]=='{'){
    			b[top++] = s[i];
    		}
    		else if(s[i]=='}'){
    			if(b[top-1]=='{'){
    				top--;
    			}
    			else return 0;
    		}
    	}
    	if(top == 0) return 1;
    	else return 0;
    }
    int main(){
    	gets(a);
    	if(rev(a)==1) printf("True
    ");
    	else printf("False
    ");
    	return 0;
    }
    

    2. 实现所给函数,完成单向链表的反转

    (不允许开辟新的空间,不允许修改所给结构/类以及函数的定义)

    注意:使用递归满分,其他视情况给分

    - 思路是把链表的所有箭头都反向,指向他前一个
    - 比如 1 -> 2 -> 3 -> 4 -> 5
    
        rev: 1 <- 2 <- 3 <- 4 <- 5
    
    - 因为是单链表 只有i->next,所以需要储存当前节点 now 和上一个节点 pre
    
        正好用递归可以实现,node *now = rev(pre->next); 当前节点now是递归的末尾节点
    
        now->next = pre , 当前节点指向上一个节点
    
        pre的下一个节点设置成NULL,然后return pre ,作为上一个节点的now,继续递归,当前节点now为空
    
        因为这个算法只改变了箭头的指向,而没有改变head 和 end,
    
        所以遍历的时候,从end开始遍历。
    
    if(now != NULL){
                now->next = pre;
                pre->next = NULL;
            }
    
    #include <bits/stdc++.h>
    using namespace std;
    struct node{
        int data;
        node *next;
    };
    class li{
        node *head,*end;
    public:
        li():head(NULL),end(NULL){}
        void push(int x){
            node *newnode = new node;
            newnode->data = x;
            newnode->next = NULL;
            if(head == NULL){
                head = newnode;
            }
            else {
                end->next = newnode;
            }
            end = newnode;
        }
        void print(){
            node *thead = head;
            while(thead!=NULL){
                cout<<thead->data<<" ";
                thead = thead->next;
            }
        }
        node *rev(node *pre){
            if(pre==NULL) return NULL;
            if(pre->next==NULL) return pre;
            node *now = rev(pre->next);
            if(now != NULL){
                now->next = pre;
                pre->next = NULL;
            }
            return pre;
        }
        void chang(){
            rev(head);
            node *tend = end;
            while(end!=NULL){
                cout<<end->data<<" ";
                end = end->next;
            }
        }
    };
    int main(){
        li A;
        int n,t;
        cin>>n;
        while(n--){
            cin>>t;
            A.push(t);
        }
        A.chang();
        return 0;
    }
    
    

    3. 使用栈实现队列的下列操作:

    push(x) -- 将一个元素放入队列的尾部。

    pop() -- 从队列首部移除元素。

    peek() -- 返回队列首部的元素。

    empty() -- 返回队列是否为空。

    - 用两个栈来模拟队列
        
        push 就是入栈
    
        pop 移除队列首部的第一个元素
        
            因为stack是 后进先出,所以尝试把stack中的每一个元素中重新装入一个新的stack
    
            这样就把原来的栈中的元素,完全颠倒了位置,达到了队列的要求(先进先出)
        peek 同样使用pop中的方法实现
        
        empty 调用stack中的empty
    
    #include <bits/stdc++.h>
    using namespace std;
    stack<int > s,q;
    void push(int i){
        s.push(i);
    }
    bool empty(){
        if(s.empty()) return 1;
        else return 0;
    }
    void pop(){
        while(!s.empty()){
            q.push(s.top());
            s.pop();
        }
        int val = q.top();
        q.pop();
        while(!q.empty()){
            s.push(q.top());
            q.pop();
        }
    }
    int peek(){
        while(!s.empty()){
            q.push(s.top());
            s.pop();
        }
        int val = q.top();
        while(!q.empty()){
            s.push(q.top());
            q.pop();
        }
        return val;
    }
    int main(){
        int x;
        string ch;
        while(1){
            cin>>ch;
            if(ch=="push"){
                cin>>x;
                push(x);
            }
            if(ch=="pop"){
                pop();
            }
            if(ch=="exit") break;
            if(ch=="peek"){
                cout<<peek()<<endl;
            }
            if(ch=="empty"){
                cout<<empty()<<endl;
            }
        }
    }
    
    

    4. 实现所给函数,实现删除链表的倒数第 n 个节点,并且返回链表的头结点。

    (不允许修改所给结构/类以及函数的定义)

    比如:一个单链表为 1->2->3->4->5,输入 n = 3 后,

    得到的答案应该
    为:1->2->4->5
    输入的 n 保证是合法有效的。

    注意:使用一遍扫描实现满分,其余视情况给分

    - 实现倒数第k个,相当于正数第n-k+1个,
    
        使用两个指针,都指向head,第一个指针先走k步,
    
        然后第二个指针再开始走,等第一个指针走到链表的尾部时,第二个指针停止的地方就是要删除的元素
    
        因为要删除它,所以应该让第二个指针指向 被删除元素的前一个元素,
        那么第一个指针就要多走一步。
    
        然后 thead->next = thead->next->next  就行了
    
        不过还要特判一下 删除倒数第n个元素,即正数第一个元素
        直接 让 head = head->next即可,就是把指针头移到第二个元素那么,当做头节点
    
    #include <bits/stdc++.h>
    using namespace std;
    struct node{
        int data;
        node *next;
    };
    class li{
        node *end,*head;
    public:
        li():end(NULL),head(NULL){}
        void push(int x){
            node *newnode = new node;
            newnode->data = x;
            newnode->next = NULL;
            if(head==NULL){
                head = newnode;
            }
            else {
                end->next = newnode;
            }
            end = newnode;
        }
        void print(){
            node *thead = head;
            while(thead!=NULL){
                cout<<thead->data<<" ";
                thead = thead->next;
            }
        }
        void updata(int i){
            node *p = head,*thead = head;
            while(i--&&p->next!=NULL) p = p->next;
            cout<<p->data<<endl;
            if(p->next==NULL) head = head->next;
            else{
                p = p->next;
                while(p!=NULL){
                    thead = thead->next;
                    p = p->next;
                }
                thead->next = thead->next->next;
            }
        }
    };
    int main(){
        li A;
        int t,n;
        cin>>n;
        for(int i=0;i<n;++i) {
            cin>>t;
            A.push(t);
        }
        A.print();
        cin>>t;
        cout<<endl;
        A.updata(t);
        A.print();
        return 0;
    }
    
    

    5. 实现一个函数,参数为两个整数a和b,且保证 a + b < 2147483647,

    函数返回他们的和,即 a + b。
    (WQH:真的以为这么简单?)

    要求:不允许使用符号 + - * /

    • 用位运算实现 +

    位运算实现加法

    #include <bits/stdc++.h>
    using namespace std;
    int add(int a,int b){
        int ret = 0;
        while(b){
            ret = a^b;
            b = (a&b)<<1;
            a = ret;
        }
    }
    int main(){
        int a,b;
        cin>>a>>b;
        cout<<add(a,b);
        return 0;
    }
    
    
  • 相关阅读:
    jdk silent install test
    jdk silent install
    PS_note_01
    string.split('',-1)的作用
    dos下静默安装
    dos命令中rem 与::的区别
    barcode4j用法
    查看tomcat的版本
    eclipse里启动rabbitmq报错 java.net.SocketException: Connection reset
    Mysql性能调优
  • 原文地址:https://www.cnblogs.com/lukelmouse/p/10533112.html
Copyright © 2011-2022 走看看