小工具知识网

当前位置: 首页 > 行业知识 > 印度小哥数据结构视频代码测试笔记

行业知识

印度小哥数据结构视频代码测试笔记

2026-11-02 21:34:31 来源:互联网转载

引子

���早看野火的开发板视频嵌入式Linux视频笔记----Linux基础入门

其中,P2 第1讲-为什么学习Linux开发 部分提到了C语言解释器GitHub - lotabout/write-a-C-interpreter: Write a simple interpreter of C. Inspired by c4 and largely based on it.

于是就看了手把手教你构建 C 语言编译器

看完发现没看懂,于是就去B站找文中提到的【如果要我说计算机专业最重要的三门课,我会说是《数据结构》、《算法》和《编译原理》。在我看来,能不能理解“递归”像是程序员的第一道门槛,而会不会写编译器则是第二道。】

于是就有了【强烈推荐】深入浅出数据结构 - 顶尖程序员图文讲解 - UP主翻译校对 (已完结)

看完了咖喱味的数据结构,感觉很有收获,于是决定把视频中的代码也测试下,就有了这篇笔记

我没翻墙,就用了评论里的别人整理的代码,修改了一点小错误,加了缩进,把部分C++代码改写为C代码

数据结构代码

全部C/C++代码在这里https://download.csdn.net/download/gzc0319/88881845?spm=1001.2014.3001.5503

正文

P13: 双向链表的实现https://gist.github.com/mycodeschool/7429492 (C)

代码

/* Doubly Linked List implementation 双向链表的实现 */#include#includestruct Node{int data;struct Node* next;struct Node* prev;};struct Node* head; // global variable - pointer to head node. 全局变量--链表头指针//Creates a new Node and returns pointer to it.  创建结点,返回指针struct Node* GetNewNode(int x) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));//动态分配内存newNode->data = x;newNode->prev = NULL;newNode->next = NULL;return newNode;}//Inserts a Node at head of doubly linked list 在链表头插入结点void InsertAtHead(int x) {struct Node* newNode = GetNewNode(x);if(head == NULL) {head = newNode;return;}head->prev = newNode;newNode->next = head;//曾经的第1个结点变为第2个结点head = newNode;}//Inserts a Node at tail of Doubly linked list 在链表尾插入结点void InsertAtTail(int x) {struct Node* temp = head;struct Node* newNode = GetNewNode(x);if(head == NULL) {head = newNode;return;}while(temp->next != NULL) temp = temp->next; // Go To last Node 寻找最后1个结点temp->next = newNode;newNode->prev = temp;}//Prints all the elements in linked list in forward traversal order 从链表头开始打印所有元素void Print() {struct Node* temp = head;printf("Forward: ");while(temp != NULL) {printf("%d ",temp->data);temp = temp->next;}printf("\n");}//Prints all elements in linked list in reverse traversal order. 从链表尾开始打印所有元素void ReversePrint() {struct Node* temp = head;if(temp == NULL) return; // empty list, exit 空链表,退出// Going to last Node 找到最后一个结点while(temp->next != NULL) {temp = temp->next;}// Traversing backward using prev pointer 使用prev指针反向遍历printf("Reverse: ");while(temp != NULL) {printf("%d ",temp->data);temp = temp->prev;}printf("\n");}int main() {/*Driver code to test the implementation*/head = NULL; // empty list. set head as NULL. // Calling an Insert and printing list both in forward as well as reverse direction. InsertAtTail(2); Print(); ReversePrint();InsertAtTail(4); Print(); ReversePrint();InsertAtHead(6); Print(); ReversePrint();InsertAtTail(8); Print(); ReversePrint();InsertAtHead(1); Print(); ReversePrint();}

运行效果

P15:使用数组实现栈 https://gist.github.com/mycodeschool/6878252 (C)

代码

// Stack - Array based implementation.  使用数组实现栈// Creating a stack of integers.  整数栈#include#define MAX_SIZE 101int A[MAX_SIZE]; // integer array to store the stack  整型数组保存栈int top = -1;// variable to mark top of stack in array 栈头// Push operation to insert an element on top of stack.  入栈void Push(int x){if(top == MAX_SIZE -1) { // overflow case. 栈满printf("Error: stack overflow\n");return;}A[++top] = x;//成功入栈}// Pop operation to remove an element from top of stack. 出栈void Pop(){if(top == -1) { // If stack is empty, pop should throw error.  栈空printf("Error: No element to pop\n");return;}top--;//成功出栈}// Top operation to return element at top of stack.  读栈顶元素int Top(){return A[top];}// This function will return 1 (true) if stack is empty, 0 (false) otherwise 空栈返回1,否则0int IsEmpty(){if(top == -1) return 1;return 0;}// This function is just to test the implementation of stack.  测试栈的实现// This will print all the elements in the stack at any stage. 打印栈中的所有元素void Print() {int i;printf("Stack: ");for(i = 0;i= '0' && C = '0' && C = 'a' && C = 'A' && C  op2Weight ? 1 : 0;}// 将中缀表达式转换为后缀表达式void InfixToPostfix(char *expression, char *postfix) {    int top = -1; // 栈顶指针    char stack[strlen(expression)]; // 栈    for (int i = 0; i  

运行效果

P22: 用数组实现队列并进行入对出对操作https://gist.github.com/mycodeschool/7331785 (C++)

代码

//用数组实现队列并进行入对出对操作#include #define MAX_SIZE 101 // 队列的最大大小// 定义一个名为Queue的结构体typedef struct {    int A[MAX_SIZE]; // 用于存储队列元素的数组    int front, rear; // 队首和队尾指针} Queue;// 初始化队列void initQueue(Queue *q) {    q->front = -1;    q->rear = -1;}// 判断队列是否为空int isEmpty(Queue *q) {    return (q->front == -1 && q->rear == -1);}// 判断队列是否已满--循环队列int isFull(Queue *q) {    return (q->rear + 1) % MAX_SIZE == q->front;}// 入队操作--对尾入对void enqueue(Queue *q, int x) {    printf("入队元素 %d\n", x);    if (isFull(q)) {        printf("错误:队列已满");        return;    }    if (isEmpty(q)) {        q->front = q->rear = 0;    }else {        q->rear = (q->rear + 1) % MAX_SIZE;    }    q->A[q->rear] = x;// 入队}// 出队操作--对头出对void dequeue(Queue *q) {    printf("出队操作");    if (isEmpty(q)) {        printf("错误:队列为空");        return;    } else if (q->front == q->rear) {        q->rear = q->front = -1;// 队列只有1个元素    } else {        q->front = (q->front + 1) % MAX_SIZE;    }}// 获取队首元素int front(Queue *q) {    if (q->front == -1) {        printf("错误:无法从空队列中返回队首元素");        return -1;    }    return q->A[q->front];}// 打印队列中的元素(仅用于测试)void print(Queue *q) {    int count = (q->rear + MAX_SIZE - q->front) % MAX_SIZE + 1;    printf("队列:");    for (int i = 0; i front + i) % MAX_SIZE; // 从队首开始循环遍历时的索引        printf("%d ", q->A[index]);    }    printf("\n\n");}int main() {    // 测试代码,打印每次入队或出队后的队列元素    Queue Q; // 创建一个队列实例    initQueue(&Q); // 初始化队列    enqueue(&Q, 2); print(&Q);    enqueue(&Q, 4); print(&Q);    enqueue(&Q, 6); print(&Q);    dequeue(&Q); print(&Q);    enqueue(&Q, 8); print(&Q);}

运行效果

P23: https://gist.github.com/mycodeschool/7331785 (C++)

同P22

P24:用链表实现队列并进行入队出队操作 https://gist.github.com/mycodeschool/7510222 (C)

代码

//用链表实现队列并进行入队出队操作#include #include // 定义链表节点结构体struct Node {    int data; // 节点存储的数据    struct Node* next; // 指向下一个节点的指针};// 两个全局变量,用于存储队列的队首和队尾节点的地址struct Node* front = NULL;struct Node* rear = NULL;// 入队操作,将1个整数插入队列尾部void Enqueue(int x) {    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));    temp->data = x;    temp->next = NULL;    if (front == NULL && rear == NULL) {//空队列        front = rear = temp;        return;    }    rear->next = temp;    rear = temp;}// 出队操作,从队列头部移除1个整数void Dequeue() {    struct Node* temp = front;    if (front == NULL) {        printf("队列为空");        return;    }    if (front == rear) {        front = rear = NULL;// 队列只有1个元素    } else {        front = front->next;    }    free(temp);}// 获取队首元素int Front() {    if (front == NULL) {        printf("队列为空");        return 0;    }    return front->data;}// 打印队列中的元素void Print() {    struct Node* temp = front;    while (temp != NULL) {        printf("%d ", temp->data);        temp = temp->next;    }    printf("\n");}int main() {    // 测试代码,每次入队或出队后打印队列中的元素    Enqueue(2); Print();    Enqueue(4); Print();    Enqueue(6); Print();    Dequeue(); Print();    Enqueue(8); Print();}

运行效果

P28:二叉搜索树的建立(插入) 与 查找 https://gist.github.com/mycodeschool/44e1a9183ab0e931f729 (C++)

代码

//二叉搜索树的建立(插入) 与 查找#include #include // 定义二叉搜索树节点结构体struct BstNode {    int data;    struct BstNode* left;    struct BstNode* right;};// 在堆中创建一个新的节点struct BstNode* GetNewNode(int data) {    struct BstNode* newNode = (struct BstNode*)malloc(sizeof(struct BstNode));    newNode->data = data;    newNode->left = newNode->right = NULL;    return newNode;}// 向二叉搜索树中插入数据,返回根节点的地址struct BstNode* Insert(struct BstNode* root, int data) {    if (root == NULL) { // 如果树为空        root = GetNewNode(data);    }    // 如果待插入的数据小于等于根节点的数据,则插入左子树    else if (data data) {        root->left = Insert(root->left, data);    }    // 否则,插入右子树    else {        root->right = Insert(root->right, data);    }    return root;}// 在二叉搜索树中搜索元素,如果找到元素则返回trueint Search(struct BstNode* root, int data) {    if (root == NULL) {        return 0;//找到    }    else if (root->data == data) {        return 1;//未找到    }    else if (data data) {        return Search(root->left, data);    }    else {        return Search(root->right, data);    }}int main() {    struct BstNode* root = NULL; // 创建一个空的二叉搜索树    /* 测试逻辑的代码 */    root = Insert(root, 15);    root = Insert(root, 10);    root = Insert(root, 20);    root = Insert(root, 25);    root = Insert(root, 8);    root = Insert(root, 12);    // 询问用户输入一个数字    int number;    printf("请输入要搜索的数字:");    scanf("%d", &number);    // 如果找到了数字,打印 "FOUND"    if (Search(root, number)) {        printf("Found\n");    }    else {        printf("Not Found\n");    }}

运行效果

P33: 使用队列按层次遍历打印二叉树结点https://gist.github.com/mycodeschool/9507131 (C++)

核心思想:从队头取出一个节点访问,将节点的子节点加入队尾

代码

//使用队列按层次遍历打印二叉树结点//核心思想:从队头取出一个节点访问,将节点的子节点加入队尾#include #include // 定义二叉树结点结构体struct Node {    char data;    struct Node *left;    struct Node *right;};// 函数:按层次遍历打印二叉树结点void LevelOrder(struct Node *root) {    if (root == NULL) return;    // 使用队列存储待遍历的结点    struct Node *queue[100];//指针数组    int front = -1, rear = -1;    // 将根结点入队    queue[++rear] = root;    // 当队列不为空时,继续遍历    while (front != rear) {        struct Node *current = queue[++front];// 出队并打印        printf("%c ", current->data);        // 左子结点入队        if (current->left != NULL) {            queue[++rear] = current->left;        }        // 右子结点入队        if (current->right != NULL) {            queue[++rear] = current->right;        }    }}// 函数:在二叉搜索树中插入结点struct Node* Insert(struct Node *root, char data) {    if (root == NULL) {        root = (struct Node *)malloc(sizeof(struct Node));        root->data = data;        root->left = root->right = NULL;    } else if (data data) {        root->left = Insert(root->left, data);    } else {        root->right = Insert(root->right, data);    }    return root;}int main() {    /* 创建示例二叉树M   B        Q A    C          Z    */    struct Node *root = NULL;    root = Insert(root, 'M'); root = Insert(root, 'B');    root = Insert(root, 'Q'); root = Insert(root, 'Z');    root = Insert(root, 'A'); root = Insert(root, 'C');    // 按层次遍历打印结点    LevelOrder(root);printf("\n");    return 0;}

运行效果

P34:使用递归进行二叉树前序 后序 中序遍历https://gist.github.com/mycodeschool/10016271 (C++)

代码

//使用递归进行二叉树前序 后序 中序遍历#include#include// 定义二叉树结点结构体struct Node {    char data;    struct Node *left;    struct Node *right;};// 前序遍历函数void Preorder(struct Node *root) {    if (root == NULL) return; // 递归结束条件:如果树/子树为空,返回并退出    printf("%c ", root->data); // 打印数据    Preorder(root->left); // 访问左子树    Preorder(root->right); // 访问右子树}// 中序遍历函数void Inorder(struct Node *root) {    if (root == NULL) return; // 递归结束条件:如果树/子树为空,返回并退出    Inorder(root->left); // 访问左子树    printf("%c ", root->data); // 打印数据    Inorder(root->right); // 访问右子树}// 后序遍历函数void Postorder(struct Node *root) {    if (root == NULL) return; // 递归结束条件:如果树/子树为空,返回并退出    Postorder(root->left); // 访问左子树    Postorder(root->right); // 访问右子树    printf("%c ", root->data); // 打印数据}// 向二叉搜索树中插入节点的函数struct Node* Insert(struct Node *root, char data) {    if (root == NULL) {        root = (struct Node *)malloc(sizeof(struct Node));        root->data = data;        root->left = root->right = NULL;    } else if (data data) {        root->left = Insert(root->left, data);    } else {        root->right = Insert(root->right, data);    }    return root;}int main() {    /* 创建示例二叉树       M B   QA   C   Z    */    struct Node *root = NULL;    root = Insert(root, 'M'); root = Insert(root, 'B');    root = Insert(root, 'Q'); root = Insert(root, 'Z');    root = Insert(root, 'A'); root = Insert(root, 'C');    // 前序遍历打印结点    printf("Preorder: ");    Preorder(root);    printf("\n");    // 中序遍历打印结点    printf("Inorder: ");    Inorder(root);    printf("\n");    // 后序遍历打印结点    printf("Postorder: ");    Postorder(root);    printf("\n");    return 0;}

运行效果

P36: 在二叉搜索树中删除指定值的节点https://gist.github.com/mycodeschool/9465a188248b624afdbf (C++)

代码

//在二叉搜索树中删除指定值的节点#include#include// 定义二叉树结点结构体struct Node {    int data;    struct Node *left;    struct Node *right;};// 查找二叉搜索树中的最小值struct Node* FindMin(struct Node* root) {    while (root->left != NULL) {        root = root->left;    }    return root;}// 在二叉搜索树中删除指定值的节点struct Node* Delete(struct Node *root, int data) {    if (root == NULL) {        return root;    } // 去左子树找else if (data data) {        root->left = Delete(root->left, data);    } // 去右子树找else if (data > root->data) {        root->right = Delete(root->right, data);    } else {// 当前结点为叶子结点,直接删除        if (root->left == NULL && root->right == NULL) {            free(root);            root = NULL;        } // 当前结点为最小的结点,当前结点父结点指向当前结点子结点else if (root->left == NULL) {            struct Node *temp = root;            root = root->right;            free(temp);        }// 当前结点为最大的结点,当前结点父结点指向当前结点子结点else if (root->right == NULL) {            struct Node *temp = root;            root = root->left;            free(temp);        }// 当前结点有两个子节点,在右子树找到最小值作为根结点,然后删除右子树重复值else {            struct Node *temp = FindMin(root->right);            root->data = temp->data;            root->right = Delete(root->right, temp->data);        }    }    return root;}// 中序遍历(相当于从小到大遍历)二叉树并打印节点值void Inorder(struct Node *root) {    if (root == NULL) {        return;    }    Inorder(root->left);    printf("%d ", root->data);    Inorder(root->right);}// 向二叉搜索树中插入节点struct Node* Insert(struct Node *root, int data) {    if (root == NULL) {        root = (struct Node*)malloc(sizeof(struct Node));        root->data = data;        root->left = root->right = NULL;    } else if (data data) {        root->left = Insert(root->left, data);    } else {        root->right = Insert(root->right, data);    }    return root;}int main() {    /* 创建一个示例二叉搜索树      5  3     101   4      11    */    struct Node* root = NULL;    root = Insert(root, 5); root = Insert(root, 10);    root = Insert(root, 3); root = Insert(root, 4);    root = Insert(root, 1); root = Insert(root, 11);    // 删除值为5的节点,可以修改这个值来测试其他情况    root = Delete(root, 5);    // 中序遍历并打印节点值    printf("Inorder: ");    Inorder(root);    printf("\n");    return 0;}

运行效果

P37: 在二叉搜索树中找到中序后继节点https://gist.github.com/mycodeschool/6515e1ec66482faf9d79 (C++)

逻辑

代码

// 在二叉搜索树中找到中序后继节点#include#include// 定义二叉树结点结构体struct Node {    int data;    struct Node *left;    struct Node *right;};// 在二叉搜索树中查找指定值的节点struct Node* Find(struct Node* root, int data) {    if (root == NULL) return NULL;    else if (root->data == data) return root;// 找到节点    else if (root->data right, data);    else return Find(root->left, data);}// 在二叉搜索树中找到最小值的节点struct Node* FindMin(struct Node* root) {    if (root == NULL) return NULL;    while (root->left != NULL)        root = root->left;    return root;}// 在二叉搜索树中找到中序后继节点struct Node* Getsuccessor(struct Node* root, int data) {    struct Node* current = Find(root, data);// 先找到data对应的节点    if (current == NULL) return NULL;    if (current->right != NULL) { // 情况1:节点有右子树,中序后继节点就是右子树最小值        return FindMin(current->right);    }    else { // 情况2:没有右子树 - O(h),中序后继节点就是某个祖先        struct Node* successor = NULL;        struct Node* ancestor = root;        while (ancestor != current) {            if (current->data data) {                successor = ancestor; // 到目前为止,这是最深节点,当前节点在其左侧                ancestor = ancestor->left;            }            else                ancestor = ancestor->right;        }        return successor;    }}// 中序遍历二叉树void Inorder(struct Node* root) {    if (root == NULL) return;    Inorder(root->left); // 访问左子树    printf("%d ", root->data); // 打印数据    Inorder(root->right); // 访问右子树}// 在二叉搜索树中插入节点struct Node* Insert(struct Node* root, int data) {    if (root == NULL) {        root = (struct Node*)malloc(sizeof(struct Node));        root->data = data;        root->left = root->right = NULL;    }    else if (data data)        root->left = Insert(root->left, data);    else        root->right = Insert(root->right, data);    return root;}int main() {    /* 创建示例二叉树         5     3   10    1   4    11    */    struct Node* root = NULL;    root = Insert(root, 5); root = Insert(root, 10);    root = Insert(root, 3); root = Insert(root, 4);    root = Insert(root, 1); root = Insert(root, 11);    // 中序遍历二叉树    printf("Inorder Traversal: ");    Inorder(root);    printf("\n");    // 查找某个节点的中序后继节点    struct Node* successor = Getsuccessor(root, 1);    if (successor == NULL) printf("No successor Found\n");    else        printf("Successor of 1 is %d\n", successor->data);}

运行效果

图邻接表的构造与遍历

代码参考《计算机软件技术基础》徐士良 算法2.29和2.30

代码

// 图邻接表的构造与遍历// 代码参考《计算机软件技术基础》徐士良 算法2.29和2.30#include "stdio.h"#include "stdlib.h"struct node// 单链表中节点结构{int num;// 图中节点编号int val;// 节点值struct node *next;};struct gpnode// 顺序存储空间中节点结构{char data;struct node *link;};// 图邻接表的构造--该函数返回顺序存储空间的首地址struct gpnode *creatgp(name,n)int n;char name[];{struct gpnode *head;struct node *p;int k,num,val;//节点编号和节点值head = (struct gpnode *)malloc(n*sizeof(struct gpnode));//顺序存储空间// 依次对图中的每一个节点建立单链表for(k=0;kdata=name[k];// A B C D E(head+k)->link=NULL;printf("input linked list of %c :\n",name[k]);scanf("%d,%d",&num,&val);// 获取节点编号和节点值while(num>0)// 编号为1 2 3 4 5{// 将新节点加入到链表头部p = (struct node *)malloc(sizeof(struct node));// 单链表节点p->num = num;p->val = val;p->next = (head+k)->link;// 新节点指向原来的第1个节点(head+k)->link = p;// 将新节点链接到单链表表头scanf("%d,%d",&num,&val);}}return head;}// 图邻接表的遍历// 递归函数void static dfs(head,k,mark)struct gpnode *head;int k,*mark;{struct node* p;printf("%c",(head+k-1)->data);// 输出当前节点值mark[k-1] = 1;// 记录当前节点的查访标志p = (head+k-1)->link;// 当前节点的第一个后件节点while(p!=NULL){if(mark[(p->num)-1]==0)// 该节点未被查访dfs(head,p->num,mark);p = p->next;}return;}void dfsgp(head,n)struct gpnode *head;int n;{int k,*mark;mark = malloc( n*sizeof(int) );// 标志数组空间for(k=0;k

上一篇:xshell怎么连db服务器?

下一篇:hand怎么读英语语音?