????? THU数据结构(上)(2023spring) 完成啦(?????)
发布人:shili8
发布时间:2025-03-12 09:03
阅读次数:0
**THU数据结构(上)课程总结**
**课程简介**
本课程是清华大学计算机系的必修课之一,主要内容包括线性表、栈、队列、树等基本数据结构的理论基础和实现。通过学习本课程,我们可以掌握这些数据结构的定义、运算、应用以及它们在实际问题中的使用。
**一、线性表**
###1.1 定义线性表是指零个或多个元素按一定顺序排列起来的集合体,通常用一个一维数组来表示。线性表的基本操作包括插入、删除和查找等。
###1.2 实现
c// 线性表的定义typedef struct { int data[100]; // 元素数组 int length; // 元素个数} LinearTable; // 线性表的初始化函数void initLinearTable(LinearTable *lt) { lt->length =0; } // 线性表的插入函数void insertLinearTable(LinearTable *lt, int pos, int value) { if (pos < 1 || pos > lt->length +1) { printf("插入位置错误! "); return; } for (int i = lt->length; i >= pos -1; i--) { lt->data[i] = lt->data[i -1]; } lt->data[pos -1] = value; lt->length++; } // 线性表的删除函数void deleteLinearTable(LinearTable *lt, int pos) { if (pos < 1 || pos > lt->length) { printf("删除位置错误! "); return; } for (int i = pos -1; i < lt->length; i++) { lt->data[i] = lt->data[i +1]; } lt->length--; } // 线性表的查找函数int searchLinearTable(LinearTable *lt, int value) { for (int i =0; i < lt->length; i++) { if (lt->data[i] == value) { return i +1; } } return -1; }
###1.3 应用线性表在实际问题中的应用非常广泛,例如:
* 链式存储结构:链式存储结构是指使用指针来连接各个元素的数据结构。链式存储结构可以有效地解决线性表中插入和删除操作的问题。
* 栈和队列:栈和队列都是基于线性表的数据结构,它们分别支持后进先出(LIFO)和先进先出(FILO)的访问顺序。
**二、栈**
###2.1 定义栈是指一个元素集合体,遵循后进先出的原则。栈的基本操作包括入栈和出栈等。
###2.2 实现
c// 栈的定义typedef struct { int data[100]; // 元素数组 int top; // 栈顶指针} Stack; // 栈的初始化函数void initStack(Stack *s) { s->top = -1; } // 栈的入栈函数void push(Stack *s, int value) { if (s->top ==99) { printf("栈已满! "); return; } s->data[++s->top] = value; } // 栈的出栈函数int pop(Stack *s) { if (s->top == -1) { printf("栈为空! "); return -1; } return s->data[s->top--]; }
###2.3 应用栈在实际问题中的应用包括:
* 表达式求值:栈可以用于表达式的求值,例如计算 `a + b * c` 等。
* 回溯算法:栈可以用于回溯算法中,例如解决迷宫问题等。
**三、队列**
###3.1 定义队列是指一个元素集合体,遵循先进先出的原则。队列的基本操作包括入队和出队等。
###3.2 实现
c// 队列的定义typedef struct { int data[100]; // 元素数组 int front; // 队头指针 int rear; // 队尾指针} Queue; // 队列的初始化函数void initQueue(Queue *q) { q->front =0; q->rear = -1; } // 队列的入队函数void enqueue(Queue *q, int value) { if (q->rear ==99) { printf("队列已满! "); return; } q->data[++q->rear] = value; } // 队列的出队函数int dequeue(Queue *q) { if (q->front > q->rear) { printf("队列为空! "); return -1; } return q->data[q->front++]; }
###3.3 应用队列在实际问题中的应用包括:
* 线程通信:队列可以用于线程之间的通信,例如生产者-消费者问题等。
* 缓冲区管理:队列可以用于缓冲区的管理,例如网络传输等。
**四、树**
###4.1 定义树是指一个元素集合体,遵循父子关系。树的基本操作包括插入和删除等。
###4.2 实现
c// 树的定义typedef struct Node { int data; // 元素值 struct Node *left; // 左孩子 struct Node *right; // 右孩子} TreeNode; // 树的初始化函数void initTree(TreeNode **root) { *root = NULL; } // 树的插入函数void insertTreeNode(TreeNode **root, int value) { if (*root == NULL) { *root = (TreeNode *)malloc(sizeof(TreeNode)); (*root)->data = value; (*root)->left = NULL; (*root)->right = NULL; } else { // 根据值大小决定插入左子树还是右子树 if ((*root)->data < value) { insertTreeNode(&(*root)->right, value); } else { insertTreeNode(&(*root)->left, value); } } } // 树的删除函数void deleteTreeNode(TreeNode **root, int value) { // 根据值大小决定删除左子树还是右子树 if ((*root)->data < value) { deleteTreeNode(&(*root)->right, value); } else if ((*root)->data > value) { deleteTreeNode(&(*root)->left, value); } else { // 找到要删除的节点 TreeNode *node = *root; // 如果只有一个孩子,直接将孩子赋值给当前节点 if (node->left == NULL && node->right == NULL) { free(node); *root = NULL; } else if (node->left != NULL && node->right == NULL) { TreeNode *temp = node->left; free(node); *root = temp; } else if (node->left == NULL && node->right != NULL) { TreeNode *temp = node->right; free(node); *root = temp; } else { // 如果有两个孩子,找到后继节点 TreeNode *predecessor = findPredecessor(&(*root)->left, value); // 将后继节点的值赋值给当前节点 (*root)->data = predecessor->data; // 删除后继节点 deleteTreeNode(&(*root)->left, value); } } } // 找到树中最小的元素int findMin(TreeNode *node) { while (node->left != NULL) { node = node->left; } return node->data; }
###4.3 应用树在实际问题中的应用包括:
* 文件系统管理:树可以用于文件系统的管理,例如目录结构等。
* 数据库索引:树可以用于数据库索引的建立和维护。
**五、总结**
本文主要介绍了线性表、栈、队列和树这四种基本数据结构的定义、实现和应用。通过学习这些数据结构,我们可以更好地理解计算机科学中的基础概念,并且能够在实际问题中运用它们来解决问题。
**参考文献**
* 《算法导论》(第三版) - Cormen, Thomas H., et al.
* 《数据结构与算