手撸数据结构

8/24/2021 DataStructureAlgorithm

一般线性表

单向链表

力扣 707:设计链表 (opens new window)

struct Node{
    int val;
    Node* next;
    Node() : val(0), next(nullptr) {}
    Node(int x) : val(x), next(nullptr) {}
    Node(int x, Node *next) : val(x), next(next) {}
};

class MyLinkedList {
public:

    Node* head;
    
    int length;

    MyLinkedList() {
        head = new Node(-1);
        length = 0;
    }

    Node* getNode(int index){
        Node* p = head->next;
        while(index > 0){
            p = p->next;
            index--;
        }
        return p;
    }
    
    int get(int index) {
        if(index >= length || index < 0){
            return -1;
        }
        return getNode(index)->val;
    }
    
    void addAtHead(int val) {
        Node* node = new Node(val, head->next);
        head->next = node;
        length++;
    }
    
    void addAtTail(int val) {
        Node* p = head;
        while(p->next){
        	p = p->next;
		}
        p->next = new Node(val);
        length++;
    }
    
    void addAtIndex(int index, int val) {
        if(index > length){
            return;
        } else if(index <= 0){
            addAtHead(val);
        } else if(index == length){
            addAtTail(val);
        } else {
            Node* node = getNode(index-1);
            Node* newNode = new Node(val, node->next);
            node->next = newNode;
            length++;
        }
    }
    
    void deleteAtIndex(int index) {
        if(index >= length || index < 0){
            return;
        }
        if(index == 0){
        	head->next = head->next->next;
        	length--;
        	return;
		}
        Node* pre = getNode(index-1);
        Node* cur = pre->next;
        Node* next = pre->next->next;
        pre->next = next;
        delete(cur);
        length--;
    }
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

栈和队列

栈的链表实现

#include <iostream>
using namespace;

struct LinkedNode {
    int val = 0;
    LinkedNode* next = nullptr;
    LinkedNode() {};
    LinkedNode(int val){
        this->val = val;
    }
    int getVal(){
        return val;
    }
};

class Stack{

private:
    int length = 0;
    LinkedNode* top = new LinkedNode();

public:
    Stack() {};
    bool empty();
    void push(int val);
    void clear();
    int pop();
    int peek();
    int size();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "Stack.h"

void Stack::push(int val) {
    LinkedNode* node = new LinkedNode(val);
    node->next = top->next;
    top->next = node;
    length++;
}

void Stack::clear() {
    top = new LinkedNode();
    length = 0;
}

int Stack::pop() {
    if (empty()) {
        cout << "The Stack Is Empty" << endl;
        return -1;
    }
    LinkedNode* temp = top->next;
    int res =temp->getVal();
    top->next = temp->next;
    free(temp);
    length--;
    return res;
}

int Stack::peek() {
    if (empty()) {
        cout << "The Stack Is Empty" << endl;
        return -1;
    }
    return top->next->getVal();
}

bool Stack::empty() {
    if (length == 0) {
        return true;
    }
    return false;
}

int Stack::size() {
    return length;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

栈的数组实现

力扣 155:最小栈 (opens new window)

class MinStack {
public:

    vector<int> stack;

    int min;

    MinStack() {
        min = INT_MAX;
    }

    void push(int val) {
        stack.push_back(val);
        if(val < min){
            min = val;
        }
    }

    void pop() {
        int index = stack.size()-1;
        int top = stack[index];
        stack.erase(stack.begin()+index);
        if(min == top){
            min = *min_element(stack.begin(), stack.end());
        }
        if(stack.size() == 0){
            min = INT_MAX;
        }
    }

    int top() {
        return stack[stack.size()-1];
    }

    int getMin() {
        return min;
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

队列的链表实现

#include <iostream>
using namespace;

struct DLinkedNode {
    int val = 0;
    DLinkedNode* next = nullptr;
    DLinkedNode* prev = nullptr;
    DLinkedNode() {};
    DLinkedNode(int val){
        this->val = val;
    }
    int getVal() {
        return val;
    }
};

class Deque{

private:
    int length = 0;
    DLinkedNode* head;
    DLinkedNode* tail;

public:
    Deque();
    void offer(int val);
    void offerFirst(int val);
    int peek();
    int peekLast();
    int poll();
    int pollLast();
    int size();
    bool empty();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "Deque.h"

int Deque::size() {
    return length;
}

Deque::Deque() {
    head = new DLinkedNode();
    tail = new DLinkedNode();
    head->next = tail;
    tail->prev = head;
}

//入队,插入到队尾
void Deque::offer(int val) {
    DLinkedNode* node = new DLinkedNode(val);
    DLinkedNode* next = head->next;
    node->prev = head;
    node->next = next;
    head->next = node;
    next->prev = node;    
    length++;
}

//入队,插入到队首
void Deque::offerFirst(int val) {
    DLinkedNode* node = new DLinkedNode(val);
    DLinkedNode* prev = tail->prev;
    node->prev = prev;
    node->next = tail;
    tail->prev = node;
    prev->next = node;
    length++;
}

//检索队首
int Deque::peek() {
    if (length == 0) {
        cout << "The Deque Is Empty" << endl;
        return -1;
    }
    return tail->prev->getVal();
}

//检索队尾
int Deque::peekLast() {
    if (length == 0) {
        cout << "The Deque Is Empty" << endl;
        return -1;
    }
    return head->next->getVal();
}

int Deque::poll() {
    if (length == 0) {
        cout << "The Deque Is Empty" << endl;
        return -1;
    }
    DLinkedNode* temp = tail->prev;
    int res = temp->getVal();
    temp->prev->next = tail;
    tail->prev = temp->prev;
    free(temp);
    length--;
    return res;
}

int Deque::pollLast() {
    if (length == 0) {
        cout << "The Deque Is Empty" << endl;
        return -1;
    }
    DLinkedNode* temp = head->next;
    int res = temp->getVal();
    temp->next->prev = head;
    head->next = temp->next;
    free(temp);
    length--;
    return res;
}


bool Deque::empty() {
    if (length == 0) {
        return true;
    }
    return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

树和图

二叉树

#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;


struct node{
    char val;
    node* l;
    node* r;
};

node* node_new(){
    node* n = new node();
    n->l = NULL;
    n->r = NULL;
    return n;
}

void tree_del(node* root){
    if(root->l != NULL){
        tree_del(root->l);
    }
    if(root->r != NULL){
        tree_del(root->r);
    }
    free(root);
}


//前序遍历 
void preorder_traversal(node* root){
    if(root->val == '#'){
        return;
    }
    cout << root->val;
    preorder_traversal(root->l);
    preorder_traversal(root->r);
}

//中序遍历 
void inorder_traversal(node* root){
    if(root->val == '#'){
        return;
    }
    inorder_traversal(root->l);
    cout << root->val;
    inorder_traversal(root->r);
}

//后序遍历 
void postorder_traversal(node* root){
    if(root->val == '#'){
        return;
    }
    postorder_traversal(root->l);
    postorder_traversal(root->r);
    cout << root->val;
}


void traversal(node* root){
    if(root->val == '#'){
        return;
    }
    preorder_traversal(root);
    cout << endl;
    inorder_traversal(root);
    cout << endl;
    postorder_traversal(root);
    cout << endl;
}



//用于记录字符数组下标位置 
static int pos = 0;
//中序构造 
void node_add(node* root, char* vals){
    //cout << vals[pos] << endl;
    root->val = vals[pos];
    if(vals[pos++] == '#'){
        //cout << "hahaha" << endl; 
        return;
    }
    root->l = node_new(); 
    node_add(root->l, vals);
    root->r = node_new();
    node_add(root->r, vals);    
}

void tree_build(node* root, char* vals){
    node_add(root, vals);
    pos = 0;
}


//求叶子个数 
int leaf(node* root){
    if(root->val == '#'){
        return 0;
    }

    if(root->l->val == '#' && root->r->val == '#'){
        return 1;
    }

    int n1 = 0, n2 = 0;
    n1 = leaf(root->l);
    n2 = leaf(root->r);

    return n1+n2;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

字典树

也叫前缀树

力扣 208:实现 Trie (前缀树) (opens new window)

class Trie {

    private Trie[] children;
    private boolean isEnd;

    public Trie() {
        children = new Trie[26];
        isEnd = false;
    }

    public void insert(String word) {
        Trie p = this;
        for(int i = 0; i < word.length(); i++){
            char c = word.charAt(i);
            int index = c-'a';
            if(p.children[index] == null){
                p.children[index] = new Trie();
            }
            p = p.children[index];
        }
        p.isEnd = true;
    }

    private Trie searchPrefix(String prefix){
        Trie p = this;
        for(int i = 0; i < prefix.length(); i++){
            char c = prefix.charAt(i);
            int index = c-'a';
            if(p.children[index] == null){
                return null;
            }
            p = p.children[index];
        }
        return p;
    }

    public boolean search(String word) {
        Trie n = searchPrefix(word);
        if(n == null || n.isEnd == false){
            return false;
        }
        return true;
    }

    public boolean startsWith(String prefix) {
        if(searchPrefix(prefix) == null){
            return false;
        }
        return true;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

无向图

自己乱写的无向图

#include <iostream>
using namespace std;
#define MAX 100

struct node{
    char val;
    int size;
    node** bro;
};

node* node_build(char v){
    node* n = new node();
    n->val = v;
    n->size = 0;
    n->bro = new node*[MAX]; 
    return n;
}

void node_del(node* v){
    /*for(int i = 0; i < v->size; i++){
        delete(v->bro[i]);
    }*/
    delete(v);
}

void node_add(node* n, node* v){
    n->bro[n->size++] = v;
    v->bro[v->size++] = n;
} 

node** map_build(int m, int n){
    char* tops = new char[m];
    cin >> tops;
    node** nodes = new node*[m];
    for(int i = 0; i < m; i++){
        nodes[i] = node_build(tops[i]);
    }
    delete(tops);
    char* connect = new char[2];
    for(int j = 0; j < n; j++){
        cin >> connect;
        node* v1 = NULL;
        node* v2 = NULL;
        for(int t = 0; t < m; t++){
            if(nodes[t]->val == connect[0]){
                v1 = nodes[t];
            }
            if(nodes[t]->val == connect[1]){
                v2 = nodes[t];
            }
        }
        node_add(v1, v2);
    }

    return nodes;
}



int main(){
    //输入顶点个数,边个数 
    int m, n;
    cin >> m >> n;
    node** map = map_build(m, n);

    for(int i = 0; i < m; i++){
        if(i != m-1)    { cout << map[i]->size << " "; }
        else            { cout << map[i]->size; }        
        delete map[i];
    }
    delete(map);

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

网上的邻接表构造无向图

#include<iostream>
using namespace std;


typedef struct ENode{ //表结点 
    char data;
    struct ENode* next; 
} ENode;


typedef struct VNode{  //头结点 
    char data;
    ENode* fistedges;
} VNode, vertex[20];


typedef struct{
    vertex v;
    int numNode,numedges;
} Graph;


int find(Graph G, char c) { //找到对应弧 
    for(int i = 0; i < G.numNode; i++)
    {
        if(G.v[i].data == c)
            return i;
     } 
    return -1;
}


void Create(Graph G) {
    cin >> G.numNode >> G.numedges;

    for(int i = 0; i < G.numNode; i++) {    //保存顶点 
        char a;
        cin >> a;
        G.v[i].data = a; 
        G.v[i].fistedges = NULL;
    }

    for(int i = 0; i < G.numedges; i++) {    //保存边 
        char a, b;
        cin >> a >> b;
        int p = find(G, a);
        int q = find(G, b);
        ENode* pre = new ENode();

         //将b接在表头a的后面    
        pre = G.v[p].fistedges;
        if(pre == NULL){
            ENode* qre = new ENode();
            qre->data = b;
            qre->next = NULL;
            G.v[p].fistedges = qre; 
        } else {
            while(pre->next != NULL) {
                pre = pre->next;
            }
            ENode* qre = new ENode();
            qre->data = b;
            qre->next = NULL;
            pre->next = qre;            
        }
        //将a接到表头b的后面
        pre = G.v[q].fistedges;
        if(pre == NULL) {
            ENode* qre = new ENode();
            qre->data = a;
            qre->next = NULL;
            G.v[q].fistedges = qre; 
        } else {
            while(pre->next != NULL) {
                pre = pre->next;
            }
            ENode* qre = new ENode();
            qre->data = a;
            qre->next = NULL;
            pre->next = qre;            
        }
    }
    //输出各个顶点的度
    for(int i = 0; i < G.numNode; i++) {
        int s = 0;
        for(ENode* p = G.v[i].fistedges; p != NULL; p = p->next) {
            s++;
        }
        if(i == 0)
            cout << s;
        else
            cout << " " << s;
     }
}

int main() {
    Graph G;
    Create(G);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Last Updated: 9/17/2024, 4:16:37 PM
妖风过海
刘森