《数据结构》严蔚敏版配套实现程序集

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:数据结构与算法是计算机科学的核心,本压缩包文件提供了《数据结构》教材中的数据结构和算法实现程序,旨在加深读者对理论的理解并提高实践能力。内容涵盖线性数据结构、树形数据结构、图数据结构、排序算法、查找算法、动态规划、贪心算法、回溯算法及分治算法,通过实际编码实践来提升编程技能和解决问题的能力。 数据结构算法实现(严蔚敏版配套实现程序)

1. 数据结构与算法基础

在当今的信息技术领域中,数据结构与算法无疑是构建强大、高效程序的基石。无论是大数据分析、人工智能,还是传统的软件开发,对数据结构和算法的精通都是一门不可或缺的技能。本章将作为引导,带领读者回到数据结构与算法的核心概念,为后续章节的深入探讨奠定坚实的基础。

1.1 理解数据结构的重要性

在程序开发过程中,数据结构扮演着至关重要的角色。它不仅关乎于数据的存储方式,更深刻影响到数据的访问效率、修改复杂度、以及扩展性。合理选择数据结构,能使得代码在处理大量数据时,依然保持卓越的性能。

1.2 算法的基本原理

算法是指导计算机完成特定任务的一系列指令。一个优秀的算法,不仅应该能够解决实际问题,还应该以最小的资源消耗来实现。在本章中,我们会简要介绍算法的时间复杂度和空间复杂度,以及如何分析算法的正确性。这些基础概念是评估算法性能的关键指标,也是学习进阶算法不可或缺的知识点。

1.3 数据结构与算法的关系

数据结构和算法之间存在着密切的联系。数据结构为算法提供了一个良好的工作平台,而算法则利用数据结构来实现特定的功能。在本章的结尾,我们将探讨如何根据不同的应用场景选择合适的数据结构与算法,进而高效地解决问题。这不仅是一种技能,更是一种艺术,需要我们在实践中不断磨练。

2. 严蔚敏《数据结构》教材配套程序

2.1 程序设计与数据结构

在深入探讨程序设计与数据结构时,我们首先要了解这两个概念的区别与联系。程序设计关注的是算法逻辑的实现和问题解决策略,而数据结构则是程序设计中对数据进行组织和管理的方式。

2.1.1 程序设计的基本概念

程序设计可以被视为一套规则和方法的集合,它涉及如何将具体问题转化为计算机能够理解并执行的指令。在程序设计的过程中,我们需要考虑到算法的效率、代码的可读性以及软件的可维护性。程序设计的两大基础是数据结构和算法,数据结构提供了数据的组织方式,而算法则定义了处理数据的步骤和规则。

在实际的程序设计中,我们会使用多种编程语言来实现我们的想法。常见的语言包括C、C++、Java、Python等,每种语言都有其特定的应用场景和优势。选择合适的编程语言是程序设计成功的关键之一。

2.1.2 数据结构的基本概念

数据结构是一门研究数据组织、管理和存储方式的学科。它不仅决定了数据的物理结构,也影响到数据处理算法的效率。在数据结构的范畴内,我们主要学习线性结构、树形结构、图结构和散列结构等。

  • 线性结构 包括数组、链表、栈和队列等,主要用于顺序存储和访问数据。
  • 树形结构 如二叉树、多叉树等,常用于表示具有层级关系的数据。
  • 图结构 用于表示复杂的网络关系,如社交网络、交通网络等。
  • 散列结构 利用散列函数,将数据分布到不同的位置上,用于实现快速的数据检索。

数据结构的选择往往取决于具体问题的需求以及对时间复杂度和空间复杂度的考虑。例如,我们需要快速检索数据时可能会选择散列表,而需要高效处理大量数据的排序和搜索操作时,则可能会使用树形结构或堆数据结构。

2.2 算法设计基础

算法是解决问题的一系列操作步骤,是程序设计的核心。一个良好的算法不仅需要正确性,还需要效率。算法效率的评估通常涉及到时间复杂度和空间复杂度。

2.2.1 算法的时间复杂度

时间复杂度是衡量算法执行时间与输入数据规模之间关系的指标。它的表示通常使用大O表示法,如O(n),O(log n),O(n^2)等。在实际应用中,我们更倾向于选择时间复杂度低的算法。

例如,在搜索一个元素时,顺序搜索的时间复杂度为O(n),而二分搜索的时间复杂度为O(log n),显然在大数据量的情况下,二分搜索会更加高效。

2.2.2 算法的空间复杂度

空间复杂度描述了算法执行过程中临时占用存储空间的大小。它也是与输入数据的规模有关的。空间复杂度的评估同样重要,特别是在资源受限的环境下,如何合理使用存储空间是一个关键问题。

例如,在实现一个简单的计数排序算法时,如果输入数据的范围非常大,那么需要使用的额外空间也会成倍增长,这时候就需要考虑空间复杂度较高的其他排序算法。

2.2.3 算法的正确性分析

算法的正确性是算法设计中最基本的要求。算法的正确性分析通常需要经过严格的数学证明来保证算法能够正确地解决特定的问题。

例如,对于一个排序算法,我们需要证明经过算法的处理后,输出的序列是有序的。正确的证明过程需要考虑所有可能的边界情况和异常情况,确保算法在任何情况下都能够正确执行。

总结来看,第二章的内容着重介绍了程序设计与数据结构以及算法设计的基础知识。在下一章节中,我们将具体探讨线性数据结构的实现以及它们的应用场景,例如数组、链表、队列和栈的结构设计与操作。

3. 线性数据结构实现(数组、链表、队列、栈)

在线性数据结构的研究中,数组、链表、队列和栈是四种基本且常用的数据结构。它们在计算机科学中占据着举足轻重的地位。它们的实现和应用不仅构成了算法设计的基础,还是理解更复杂数据结构和算法的关键。

3.1 数组与链表的实现与应用

数组与链表是两种基本的线性数据结构,它们在逻辑上都是线性排列的,但是在物理存储结构上有很大差异。这种差异导致了它们在使用上的不同特点和应用场景。

3.1.1 数组的结构设计与操作

数组是一种元素线性排列的数据结构,每个元素通过索引进行访问。它在内存中是一块连续的存储区域,因此具有常数时间的访问效率。但当元素频繁增删时,可能导致数组的移动,影响性能。

#define MAX_SIZE 10 // 定义数组的最大长度
int array[MAX_SIZE]; // 声明一个整型数组

// 初始化数组
void init_array(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        arr[i] = 0;
    }
}

// 向数组添加元素
bool add_element(int arr[], int size, int element) {
    if (size >= MAX_SIZE) return false; // 检查数组是否已满
    arr[size] = element;
    return true;
}

在上述代码中, init_array 函数初始化一个数组,所有元素被设置为 0。 add_element 函数用于在数组的末尾添加一个新元素。由于数组是固定大小的,因此在添加元素前必须检查是否有空间。

3.1.2 链表的节点设计与操作

链表由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。链表不要求内存连续,所以可以动态地进行元素的增加和删除。但访问元素需要从头开始遍历,直到找到目标元素。

typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 创建链表节点
Node* create_node(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        // 处理内存分配失败的情况
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 向链表末尾添加节点
void append_node(Node** head, int data) {
    Node* newNode = create_node(data);
    if (*head == NULL) {
        *head = newNode;
        return;
    }
    Node* current = *head;
    while (current->next != NULL) {
        current = current->next;
    }
    current->next = newNode;
}

上面的代码展示了如何定义链表节点和向链表添加新节点的基本操作。 create_node 函数创建一个新的链表节点, append_node 函数将新节点添加到链表的末尾。

3.2 队列与栈的实现与应用

队列和栈都是操作受限的数据结构,它们允许在特定的一端添加元素(入队/入栈),而在另一端移除元素(出队/出栈)。这两种数据结构在计算机科学和日常生活中都有广泛的应用。

3.2.1 队列的基本操作与应用场景

队列是一种先进先出(FIFO)的数据结构,它允许在队尾添加元素(入队),而在队首移除元素(出队)。队列在操作系统的任务调度、打印任务管理中都十分常见。

typedef struct Queue {
    Node* front;
    Node* rear;
} Queue;

// 初始化队列
void init_queue(Queue* q) {
    q->front = q->rear = NULL;
}

// 入队操作
bool enqueue(Queue* q, int value) {
    Node* newNode = create_node(value);
    if (newNode == NULL) return false;
    if (q->rear == NULL) {
        q->front = q->rear = newNode;
        return true;
    }
    q->rear->next = newNode;
    q->rear = newNode;
    return true;
}

// 出队操作
bool dequeue(Queue* q, int* value) {
    if (q->front == NULL) return false;
    Node* temp = q->front;
    *value = temp->data;
    q->front = q->front->next;
    if (q->front == NULL) {
        q->rear = NULL;
    }
    free(temp);
    return true;
}

这里展示了队列的基本操作实现。 enqueue 函数执行入队操作,而 dequeue 函数执行出队操作。需要注意的是,出队操作中需要释放被移除节点的内存,以避免内存泄漏。

3.2.2 栈的基本操作与应用场景

栈是一种后进先出(LIFO)的数据结构,它只允许在栈顶添加和移除元素(入栈/出栈)。栈在表达式求值、函数调用管理以及撤销操作中有着非常重要的应用。

typedef struct Stack {
    Node* top;
} Stack;

// 初始化栈
void init_stack(Stack* s) {
    s->top = NULL;
}

// 入栈操作
bool push(Stack* s, int value) {
    Node* newNode = create_node(value);
    if (newNode == NULL) return false;
    newNode->next = s->top;
    s->top = newNode;
    return true;
}

// 出栈操作
bool pop(Stack* s, int* value) {
    if (s->top == NULL) return false;
    Node* temp = s->top;
    *value = temp->data;
    s->top = s->top->next;
    free(temp);
    return true;
}

上述代码定义了栈的基本操作,包括初始化栈( init_stack )、入栈( push )和出栈( pop )。这些操作确保了栈的后进先出特性。需要注意的是,栈的实现比队列更为简单,因为它只需要管理一个指针即可。

通过对比队列和栈,我们不难发现,虽然它们在操作上有共同点,但是应用场景和逻辑处理方式却大相径庭。了解这些基本线性数据结构的特点和使用,对于深入学习数据结构与算法至关重要。在后续章节中,我们将深入探讨树形数据结构和图数据结构的实现与应用,它们在处理复杂数据关系时发挥着关键作用。

4. 树形数据结构实现(二叉树、平衡树、堆)

4.1 二叉树的构造与遍历

4.1.1 二叉树的构建方法

二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。二叉树是许多复杂数据结构的基础,比如堆、二叉搜索树等。二叉树的构建是通过递归或迭代的方式将数据插入到树结构中,保证每个节点的左子树和右子树满足特定的性质,比如二叉搜索树中的左子树节点值都小于根节点,右子树节点值都大于根节点。

构建二叉树的过程中,我们通常遵循递归的模式。以下是使用Python语言构建普通二叉树的示例代码:

class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

def insert(root, value):
    if root is None:
        return TreeNode(value)
    else:
        if value < root.value:
            root.left = insert(root.left, value)
        else:
            root.right = insert(root.right, value)
    return root

在这个示例中,我们首先定义了一个 TreeNode 类,用于表示树的节点。然后定义了 insert 函数,它以递归的方式实现二叉树的插入功能。如果当前的根节点为空,我们创建一个新的 TreeNode 实例,并返回它。如果根节点存在,我们就根据值的大小递归地插入到左子树或右子树中。

4.1.2 前序、中序、后序遍历的实现

遍历二叉树是算法中常见的操作之一,主要分为前序遍历、中序遍历和后序遍历三种方式。前序遍历的顺序是根节点-左子树-右子树,中序遍历的顺序是左子树-根节点-右子树,后序遍历的顺序是左子树-右子树-根节点。

以下是三种遍历方法的Python实现代码:

# 前序遍历
def preorder_traversal(root):
    if root:
        print(root.value, end=' ')
        preorder_traversal(root.left)
        preorder_traversal(root.right)

# 中序遍历
def inorder_traversal(root):
    if root:
        inorder_traversal(root.left)
        print(root.value, end=' ')
        inorder_traversal(root.right)

# 后序遍历
def postorder_traversal(root):
    if root:
        postorder_traversal(root.left)
        postorder_traversal(root.right)
        print(root.value, end=' ')

在每个遍历函数中,首先检查当前节点是否为空。如果不为空,按照前序、中序或后序的顺序访问节点值,并递归遍历左子树和右子树。

通过构建二叉树和进行遍历,我们可以更好地理解和操作这种重要的数据结构。在后续的章节中,我们将讨论如何维护平衡二叉树(如AVL树)以及如何实现堆数据结构和调整算法。

5. 图数据结构遍历与应用(深度优先搜索、广度优先搜索)

5.1 图的表示与遍历

5.1.1 图的邻接矩阵与邻接表表示

图是数据结构中的复杂类型之一,通常用于表示节点和连接这些节点的边的关系。在算法设计中,图的表示方式对算法的效率影响很大。图可以用邻接矩阵和邻接表两种主要的数据结构表示。

邻接矩阵是一个二维数组,其中行和列分别代表图中的顶点,如果顶点i和顶点j之间有边相连,则矩阵中的元素matrix[i][j]为1或边的权重,否则为0。邻接矩阵易于实现并可以直接判断任意两点之间是否存在边,但其缺点是空间复杂度较高,尤其适用于顶点数目不多的图。

邻接表是一种通过链表来存储图的表示方式,每行或每列只存储非零元素,因此节省空间。每个顶点对应一个链表,链表中的节点包含邻接顶点信息。邻接表空间效率高,尤其适合稀疏图的存储。

5.1.2 深度优先搜索算法实现

深度优先搜索(DFS, Depth-First Search)是一种用于遍历或搜索树或图的算法。DFS沿着树的深度遍历树的节点,尽可能深的搜索图的分支。

DFS的实现一般使用递归或栈。以下是使用递归的DFS算法的伪代码:

DFS(node):
    if node is visited:
        return
    mark node as visited
    for each neighbor of node:
        DFS(neighbor)

在代码中,首先检查节点是否已经被访问,如果是,则跳过。否则,标记节点为已访问,并递归地对每个邻接节点执行深度优先搜索。

5.1.3 广度优先搜索算法实现

广度优先搜索(BFS, Breadth-First Search)也是一种用于遍历或搜索树或图的算法。它从一个节点开始,逐层向周围扩散。

BFS通常使用队列来实现。以下是使用队列的BFS算法的伪代码:

BFS(start_node):
    create a queue q
    mark start_node as visited
    enqueue start_node to q
    while q is not empty:
        node = q.dequeue()
        process node
        for each neighbor of node:
            if neighbor is not visited:
                mark neighbor as visited
                enqueue neighbor to q

在实现中,从起始节点开始,将其加入队列,并标记为已访问。然后在队列非空的情况下重复执行以下步骤:从队列中弹出节点,处理该节点,然后将其所有未访问的邻居加入队列并标记为已访问。

5.2 图的应用实例分析

5.2.1 最小生成树问题的图算法应用

最小生成树是图论中的一个经典问题,指的是在一个加权无向图中找到一棵包含所有顶点且边的权值总和最小的树。常用的最小生成树算法有Kruskal算法和Prim算法。

Kruskal算法按边的权重排序,从最小的边开始,如果这条边连接的两个顶点在生成树中不在同一个连通分量内,就将这条边添加到生成树中。重复这个过程直到所有的顶点都在同一个连通分量中。

Prim算法从图中的某个顶点开始,不断添加权重最小且未被访问过的边和顶点到当前生成树的集合中,直到所有顶点都被访问。

5.2.2 最短路径问题的图算法应用

最短路径问题是指在一个图中找到两个顶点之间的最短路径。Dijkstra算法和Bellman-Ford算法是解决这个问题的两种常见算法。

Dijkstra算法适用于没有负权边的图。它使用优先队列来维护当前找到的最短路径,并逐步扩展到其他顶点。

Bellman-Ford算法则可以处理带负权边的情况,但是效率相对较低。它通过逐步松弛每条边,检查是否存在更短的路径。

通过以上的分析,我们可以看到图数据结构在处理实际问题时的强大能力。DFS和BFS为图的搜索和遍历提供了基础工具,而最小生成树和最短路径算法则在解决实际应用问题上表现出色。理解这些算法的原理和实现方式,对于从事相关领域的IT专业人员来说是必不可少的技能。

6. 算法实现与应用

6.1 排序算法的实现

排序是算法设计中一项基础而核心的任务,常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序、归并排序和堆排序等。在本节中,我们将逐一探讨这些算法的实现细节及适用场景。

6.1.1 常见的排序算法对比

不同的排序算法有不同的时间复杂度和空间复杂度。在选择排序算法时,需要根据数据的规模、数据分布以及系统资源来做出合理的决策。下表对比了各种排序算法的平均和最坏情况下的时间复杂度以及空间复杂度。

| 排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 | |------------|----------------|----------------|------------|--------| | 冒泡排序 | O(n^2) | O(n^2) | O(1) | 稳定 | | 插入排序 | O(n^2) | O(n^2) | O(1) | 稳定 | | 选择排序 | O(n^2) | O(n^2) | O(1) | 不稳定 | | 快速排序 | O(n log n) | O(n^2) | O(log n) | 不稳定 | | 归并排序 | O(n log n) | O(n log n) | O(n) | 稳定 | | 堆排序 | O(n log n) | O(n log n) | O(1) | 不稳定 |

6.1.2 冒泡排序、插入排序的实现

接下来,我们将实现冒泡排序和插入排序这两种简单的排序算法。

冒泡排序的代码实现
def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]

该算法通过不断比较相邻元素并将较大者“冒泡”到较高位置上,直到整个列表有序。

插入排序的代码实现
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i-1
        while j >= 0 and key < arr[j]:
            arr[j+1] = arr[j]
            j -= 1
        arr[j+1] = key

插入排序通过对数组中的元素进行遍历,并在适当的位置上插入,从而保持数组的有序性。

6.1.3 选择排序、快速排序的实现

选择排序和快速排序是另外两种经常被使用的排序算法。

选择排序的代码实现
def selection_sort(arr):
    for i in range(len(arr)):
        min_idx = i
        for j in range(i+1, len(arr)):
            if arr[min_idx] > arr[j]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]

选择排序通过每次从未排序部分选择最小(或最大)的元素放到已排序序列的末尾。

快速排序的代码实现
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

快速排序通过分而治之的方法,选择一个"基准"(pivot),将数组分为左右两部分,并递归地对这两部分继续进行排序。

6.1.4 归并排序、堆排序的实现

归并排序和堆排序则分别适用于不同的应用场景。

归并排序的代码实现
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    result = []
    while left and right:
        result.append(left.pop(0) if left[0] < right[0] else right.pop(0))
    result.extend(left or right)
    return result

归并排序首先将数组分割到最小单元,然后将这些单元两两合并,直至合并到完整数组。

堆排序的代码实现
def heapify(arr, n, i):
    largest = i
    left = 2*i + 1
    right = 2*i + 2
    if left < n and arr[i] < arr[left]:
        largest = left
    if right < n and arr[largest] < arr[right]:
        largest = right
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

def heap_sort(arr):
    n = len(arr)
    for i in range(n//2 - 1, -1, -1):
        heapify(arr, n, i)
    for i in range(n-1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)

堆排序通过构建最大堆或最小堆结构,然后依次移除堆顶元素并调整堆结构,达到排序目的。

通过以上代码实例,我们实现了多种基本的排序算法,了解了它们的工作原理和实现方式。在实际应用中,根据不同的需求和数据特性,我们可灵活选择合适的排序算法来解决问题。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:数据结构与算法是计算机科学的核心,本压缩包文件提供了《数据结构》教材中的数据结构和算法实现程序,旨在加深读者对理论的理解并提高实践能力。内容涵盖线性数据结构、树形数据结构、图数据结构、排序算法、查找算法、动态规划、贪心算法、回溯算法及分治算法,通过实际编码实践来提升编程技能和解决问题的能力。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

1.1 数组和字符串 2 1.1.1 一维数组的倒置 2 范例1-1 一维数组的倒置 2 ∷相关函数:fun函数 1.1.2 一维数组应用 3 范例1-2 一维数组应用 3 1.1.3 一维数组的高级应用 5 范例1-3 一维数组的高级应用 5 1.1.4 显示杨辉三角 7 范例1-4 显示杨辉三角 7 ∷相关函数:c函数 8 1.1.5 魔方阵 9 范例1-5 魔方阵 9 1.1.6 三维数组的表示 14 范例1-6 三维数组的表示 14 ∷相关函数:InitArray函数 1.1.7 多项式的数组表示 17 范例1-7 多项式数组的表示 17 1.1.8 查找矩阵的马鞍点 19 范例1-8 查找矩阵的马鞍点 19 ∷相关函数:Get_Saddle函数 1.1.9 对角矩阵建立 21 范例1-9 对角矩阵建立 21 ∷相关函数:Store函数 1.1.10 三对角矩阵的建立 22 范例1-10 三对角矩阵的建立 22 ∷相关函数:Store函数 1.1.11 三角矩阵建立 24 范例1-11 三角矩阵建立 24 ∷相关函数:Store函数 1.1.12 对称矩阵的建立 25 范例1-12 对称矩阵的建立 25 ∷相关函数:store函数 1.1.13 字符串长度的计算 28 范例1-13 字符串长度的计算 28 ∷相关函数:strlen函数 1.1.14 字符串的复制 29 范例1-14 字符串的复制 29 ∷相关函数:strcpy函数 1.1.15 字符串的替换 31 范例1-15 字符串的替换 31 ∷相关函数:strrep函数 1.1.16 字符串的删除 33 范例1-16 字符串的删除 33 ∷相关函数:strdel函数 1.1.17 字符串的比较 35 范例1-17 字符串的比较 35 ∷相关函数:strcmp函数 1.1.18 字符串的抽取 36 范例1-18 字符串的抽取 36 ∷相关函数:substr函数 1.1.19 字符串的分割 38 范例1-19 字符串的分割 38 ∷相关函数:partition函数 1.1.20 字符串的插入 40 范例1-20 字符串的插入 40 ∷相关函数:insert函数 1.1.21 字符串的匹配 42 范例1-21 字符串的匹配 42 ∷相关函数:nfind函数 1.1.22 字符串的合并 43 范例1-22 字符串的合并 43 ∷相关函数:catstr函数 1.1.23 文本编辑 45 范例1-23 文本编辑 45 ∷相关函数:StrAssign函数 1.2 栈和队列 54 1.2.1 用数组仿真堆栈 54 范例1-24 用数组仿真堆栈 54 ∷相关函数:push函数 pop函数 1.2.2 用链表仿真堆栈 57 范例1-25 用链表仿真堆栈 57 ∷相关函数:push函数 pop函数 1.2.3 顺序栈公用 59 范例1-26 顺序栈公用 59 ∷相关函数:push函数 pop函数 1.2.4 进制转换问题 61 范例1-27 进制转换问题 61 ∷相关函数:MultiBaseOutput函数 1.2.5 顺序队列操作 64 范例1-28 顺序队列操作 64 ∷相关函数:push函数 pop函数 1.2.6 循环队列 66 范例1-29 循环队列 66 ∷相关函数:EnQueue函数 DeQueue函数 1.2.7 链队列的入队、出队 69 范例1-30 链队列入队、出队 69 ∷相关函数:push函数 pop函数 1.2.8 舞伴问题 71 范例1-31 舞伴问题 71 ∷相关函数:EnQueue函数 DeQueue函数 DancePartner函数 1.3 链表 75 1.3.1 头插法建立单链表 75 范例1-32 头插法建立单链表 75 ∷相关函数:createlist函数 1.3.2 限制链表长度建立单链表 77 范例1-33 限制链表长度建立长单链表 77 ∷相关函数:createlist函数 1.3.3 尾插法建立单链表 79 范例1-34 尾插法建立单链表 79 ∷相关函数:createlist函数 1.3.4 按序号查找单链表 80 范例1-35 按序号查找单链表 80 ∷相关函数:getnode函数 1.3.5 按值查找单链表 82 范例1-36 按值查找单链表 82 ∷相关函数:locatenode函数 1.3.6 链表的插入 84 范例1-37 链表的插入 84 ∷相关函数:insertnode函数 1.3.7 链表的删除 86 范例1-38 链表的删除 86 ∷相关函数:deletelist函数 1.3.8 归并两个单链表 88 范例1-39 归并两个单链表 88 ∷相关函数:concatenate函数 1.3.9 动态堆栈 90 范例1-40 动态堆栈 90 ∷相关函数:push函数 Pop函数 1.3.10 动态队列 93 范例1-41 动态队列 93 ∷相关函数:Enqueue函数 1.3.11 初始化单循环链表 95 范例1-42 初始化单循环链表 95 ∷相关函数:ListLength_CL函数 1.3.12 查询元素的前驱和后继 98 范例1-43 查询元素的前驱和后继 98 ∷相关函数:PriorElem_CL函数 NextElem_CL函数 1.3.13 单循环链表中元素的删除 101 范例1-44 单循环链表中元素的删除 101 ∷相关函数:ListDelete_CL函数 1.3.14 单循环链表的清除和销毁 107 范例1-45 单循环链表的清除和销毁 107 ∷相关函数:DestroyList函数 1.3.15 仅设表尾指针循环链表的合并 110 范例1-46 仅设表尾指针循环链表的合并 110 ∷相关函数:MergeList_CL函数 1.3.16 正序输出双向链表 113 范例1-47 正序输出双向链表 113 ∷相关函数:ListInsert函数 ListTraverse函数 1.3.17 逆向输出双向链表 116 范例1-48 三角矩阵建立 116 ∷相关函数:ListTraverseBack函数 1.3.18 删除双向链表中的节点 121 范例1-49 删除双向链表中的节点 121 ∷相关函数:ListDelete函数 1.3.19 双向链表的元素个数 124 范例1-50 双向链表的元素个数 124 ∷相关函数:ListLength函数 1.3.20 判断双向链表是否为空 126 范例1-51 判断双向链表是否为空 126 ∷相关函数:ListEmpty函数 1.3.21 双向链表元素值的查询 129 范例1-52 双向链表元素值的查询 129 ∷相关函数:GetElemP函数 1.3.22 稀疏矩阵的建立 136 范例1-53 稀疏矩阵的建立 136 ∷相关函数:Create函数 1.3.23 稀疏矩阵的删除 138 范例1-54 稀疏矩阵的删除 138 ∷相关函数:erase函数 1.4 树和二叉树 141 1.4.1 获得二叉树的深度和根(顺序结构) 141 范例1-55 获得二叉树的深度和根 141 ∷相关函数:BiTreeDepth函数 Root函数 1.4.2 获得二叉树的深度和根(链表结构) 144 范例1-56 获得二叉树的深度和根 144 ∷相关函数:BiTreeDepth函数 Root函数 1.4.3 树的插入(顺序结构) 147 范例1-57 树的插入 147 ∷相关函数:InsertChild函数 1.4.4 节点的修改(顺序结构) 150 范例1-58 节点的修改 150 ∷相关函数:Assign函数 1.4.5 节点的修改(链式结构) 154 范例1-59 节点的修改 154 ∷相关函数:Assign函数 1.4.6 双亲、孩子和兄弟节点的查询(顺序结构) 158 范例1-60 双亲、孩子和兄弟节点的查询 158 ∷相关函数:Parent函数 LeftChild函数 RightChild函数 LeftSibling函数 RightSibling函数 1.4.7 双亲、孩子和兄弟节点的查询(链式结构) 162 范例1-61 双亲、孩子和兄弟节点的查询 162 ∷相关函数:Parent函数 LeftChild函数 RightChild函数 LeftSibling函数 RightSibling函数 1.4.8 中序遍历二叉树(顺序结构) 169 范例1-62 中序遍历二叉树 169 ∷相关函数:InOrderTraverse函数 1.4.9 中序遍历二叉树(链式结构) 171 范例1-63 中序遍历二叉树 171 ∷相关函数:InOrderTraverse函数 1.4.10 中序非递归遍历二叉树(链式结构)(1) 174 范例1-64 中序非递归遍历二叉树 174 ∷相关函数:InOrderTraverse函数 1.4.11 中序非递归遍历二叉树(链式结构)(2) 177 范例1-65 中序非递归遍历二叉树 177 ∷相关函数:InOrderTraverse2函数 1.4.12 后序遍历二叉树(顺序结构) 180 范例1-66 后序遍历二叉树 180 ∷相关函数:PostOrderTraverse函数 1.4.13 后序遍历二叉树(链式结构) 183 范例1-67 后序遍历二叉树 183 ∷相关函数:PostOrderTraverse函数 1.4.14 层次遍历二叉树(顺序结构) 186 范例1-68 层次遍历二叉树 186 ∷相关函数:LevelOrderTraverse函数 1.4.15 层次遍历二叉树(链式结构) 188 范例1-68 层次遍历二叉树 188 ∷相关函数:LevelOrderTraverse函数 1.4.16 树的合并 191 范例1-70 树的合并 191 ∷相关函数:Find函数 Union函数 1.4.17 树的二叉链表存储的基本操作 193 范例1-71 树的二叉链表存储的基本操作 193 ∷相关函数:LevelOrderTraverse函数 1.4.18 二叉树的三叉链表存储的基本操作 201 范例1-72 二叉树的三叉链表存储表示 201 ∷相关函数:CreateBiTree函数 1.4.19 二叉树的二叉线索存储的基本操作 212 范例1-73 二叉树的二叉线索存储 212 ∷相关函数:CreateBiThrTree函数 1.4.20 树的双亲表存储的基本操作 215 范例1-74 树的双亲表存储的基本操作 215 ∷相关函数:CreateTree函数 1.4.21 哈夫曼编码(1) 223 范例1-75 哈夫曼编码(1) 223 ∷相关函数:HuffmanCoding函数 1.4.22 哈夫曼编码(2) 226 范例1-76 哈夫曼编码(2) 226 ∷相关函数:HuffmanCoding函数 1.5 排序 229 1.5.1 直接插入排序 229 范例1-77 直接插入排序 229 ∷相关函数:InsertSort函数 1.5.2 折半插入排序(顺序结构) 231 范例1-78 折半插入排序(顺序结构) 231 ∷相关函数:BInsertSort函数 1.5.3 2—路插入排序(顺序结构) 233 范例1-79 2—路插入排序(顺序结构) 233 ∷相关函数:P2_InsertSort函数 1.5.4 折半插入排序(链式结构) 235 范例1-80 折半插入排序(链式结构) 235 ∷相关函数:Arrange函数 1.5.5 2—路插入排序(链式结构) 238 范例1-81 2—路插入排序(链式结构) 238 ∷相关函数:Rearrange函数 1.5.6 希尔排序 241 范例1-82 希尔排序 241 ∷相关函数:ShellSort函数 1.5.7 冒泡排序 243 范例1-83 冒泡排序 243 ∷相关函数:bubble_sort函数 1.5.8 一趟快速排序 246 范例1-84 一趟快速排序 246 ∷相关函数:QSort函数 1.5.9 一趟快速排序的改进算法 248 范例1-85 一趟快速排序的改进算法 248 ∷相关函数:QuickSort函数 1.5.10 简单选择排序 250 范例1-86 简单选择排序 250 ∷相关函数:SelectSort函数 1.5.11 箱子排序 252 范例1-87 箱子排序 252 ∷相关函数:sort函数 1.5.12 树型选择排序 254 范例1-88 树型选择排序 254 ∷相关函数:TreeSort函数 1.5.13 堆排序 256 范例1-89 堆排序 256 ∷相关函数:HeapSort函数 1.5.14 归并排序 258 范例1-90 归并排序 258 ∷相关函数:MergeSort函数 1.5.15 多路平衡归并排序 260 范例1-91 多路平衡归并排序 260 ∷相关函数:K_Merge函数 1.5.16 置换—选择排序 265 范例1-92 置换—选择排序 265 ∷相关函数:Replace_Selection函数 1.5.17 文件的归并 269 范例1-93 文件的归并 269 ∷相关函数:K_Merge函数 1.6 查找 272 1.6.1 顺序表的查找 273 范例1-94 顺序表的查找 273 ∷相关函数:Search_Seq函数 1.6.2 静态树表的查找 276 范例1-95 静态树表的查找 276 ∷相关函数:Search_SOSTree函数 1.6.3 二叉排序树的基本操作 280 范例1-96 二叉排序树的基本操作 280 ∷相关函数:InsertBST函数 1.6.4 平衡二叉树的基本操作 285 范例1-97 平衡二叉树的基本操作 285 ∷相关函数:SearchBST函数 1.6.5 B树的基本操作 290 范例1-98 B树的基本操作 290 ∷相关函数:SearchBTree函数 1.6.6 按关键字符串的遍历双链键树 295 范例1-99 按关键字符串遍历双链键树 295 ∷相关函数:SearchDLTree函数 1.6.7 按关键字符串的遍历Trie树 301 范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102 图的邻接矩阵存储表示 ∷相关函数:CreateFAG函数 CreateDG函数 1.7.2 图的邻接表存储表示 324 范例1-103 图的邻接表存储表示 324 ∷相关函数:CreateFAG函数 1.7.3 有向图的十字链表存储表示 335 范例1-104 有向图的十字链表存储表示 335 ∷相关函数:CreateDG函数 1.7.4 无向图的邻接多重表存储表示 344 范例1-105 无向图的邻接多重表存储表示 344 ∷相关函数:CreateGraph函数 1.7.5 最小生成树 355 范例1-106 最小生成树 355 ∷相关函数:MiniSpanTree_PRIM函数 1.7.6 关节点和重连通分量 359 范例1-107 关节点和重连通分量 359 ∷相关函数:FindArticul函数 1.7.7 拓扑排序 366 范例1-108 拓扑排序 366 ∷相关函数:TopologicalSort函数 1.7.8 关键路径 374 范例1-109 关键路径 374 ∷相关函数:CriticalPath函数 1.7.9 最短路径 383 范例1-110 最短路径 383 ∷相关函数:ShortestPath_DIJ函数 1.7.10 每一对顶点之间的最短路径 387 范例1-111 每一对顶点之间的最短路径 387 ∷相关函数:ShortestPath_FLOYD函数
数据结构》(C语言)是为“数据结构”课程编写的教材,也可作为学习数据结构及其算法的C程序设计的参数教材。学了数据结构后,许多以前写起来很繁杂的代码现在写起来很清晰明了. 本书的前半部分从抽象数据类型的角度讨论各种基本类型的数据结构及其应用;后半部分主要讨论查找和排序的各种实现方法及其综合分析比较。 全书采用类C语言作为数据结构和算法的描述语言。 本书概念表述严谨,逻辑推理严密,语言精炼,用词达意,并有配套的《数据结构》(C语言),便于教学,又便于自学。 本书后附有光盘。光盘内容可在DOS环境下运行的以类C语言描述的“数据结构算法动态模拟辅助教学软件,以及在Windows环境下运行的以类PASCAL或类C两种语言描述的“数据结构算法动态模拟辅助教学软件”。内附 数据结构算法实现严蔚敏配套实现程序) 目录: 第1章 绪论 1.1 什么是数据结构 1.2 基本概念和术语 1.3 抽象数据类型的表现与实现 1.4 算法和算法分析 第2章 线性表 2.1 线性表的类型定义 2.2 线性表的顺序表示和实现 2.3 线性表的链式表示和实现 2.4 一元多项式的表示及相加 第3章 栈和队列 3.1 栈 3.2 栈的应有和举例 3.3 栈与递归的实现 3.4 队列 3.5 离散事件模拟 第4章 串 4.1 串类型的定义 4.2 串的表示和实现 4.3 串的模式匹配算法 4.4 串操作应用举例 第5章 数组和广义表 5.1 数组的定义 5.2 数组的顺序表现和实现 5.3 矩阵的压缩存储 5.4 广义表的定义 5.5 广义表的储存结构 5.6 m元多项式的表示 5.7 广义表的递归算法第6章 树和二叉树 6.1 树的定义和基本术语 6.2 二叉树 6.2.1 二叉树的定义 6.2.2 二叉树的性质 6.2.3 二叉树的存储结构 6.3 遍历二叉树和线索二叉树 6.3.1 遍历二叉树 6.3.2 线索二叉树 6.4 树和森林 6.4.1 树的存储结构 6.4.2 森林与二叉树的转换 6.4.3 树和森林的遍历 6.5 树与等价问题 6.6 赫夫曼树及其应用 6.6.1 最优二叉树(赫夫曼树) 6.6.2 赫夫曼编码 6.7 回溯法与树的遍历 6.8 树的计数 第7章 图 7.1 图的定义和术语 7.2 图的存储结构 7.2.1 数组表示法 7.2.2 邻接表 7.2.3 十字链表 7.2.4 邻接多重表 7.3 图的遍历 7.3.1 深度优先搜索 7.3.2 广度优先搜索 7.4 图的连通性问题 7.4.1 无向图的连通分量和生成树 7.4.2 有向图的强连通分量 7.4.3 最小生成树 7.4.4 关节点和重连通分量 7.5 有向无环图及其应用 7.5.1 拓扑排序 7.5.2 关键路径 7.6 最短路径 7.6.1 从某个源点到其余各顶点的最短路径 7.6.2 每一对顶点之间的最短路径 第8章 动态存储管理 8.1 概述 8.2 可利用空间表及分配方法 8.3 边界标识法 8.3.1 可利用空间表的结构 8.3.2 分配算法 8.3.3 回收算法 8.4 伙伴系统 8.4.1 可利用空间表的结构 8.4.2 分配算法 8.4.3 回收算法 8.5 无用单元收 8.6 存储紧缩 第9章 查找 9.1 静态查找表 9.1.1 顺序表的查找 9.1.2 有序表的查找 9.1.3 静态树表的查找 9.1.4 索引顺序表的查找 9.2 动态查找表 9.2.1 二叉排序树和平衡二叉树 9.2.2 B树和B+树 9.2.3 键树 9.3 哈希表 9.3.1 什么是哈希表 9.3.2 哈希函数的构造方法 9.3.3 处理冲突的方法 9.3.4 哈希表的查找及其分析 第10章 内部排序 10.1 概述 10.2 插入排序 10.2.1 直接插入排序 10.2.2 其他插入排序 10.2.3 希尔排序 10.3 快速排序 10.4 选择排序 10.4.1 简单选择排序 10.4.2 树形选择排序 10.4.3 堆排序 10.5 归并排序 10.6 基数排序 10.6.1 多关键字的排序 10.6.2 链式基数排序 10.7 各种内部排序方法的比较讨论 第11章 外部排序 11.1 外存信息的存取 11.2 外部排序的方法 11.3 多路平衡归并的实现 11.4 置换一选择排序 11.5 最佳归并树 第12章 文件 12.1 有关文件的基本概念 12.2 顺序文件 12.3 索引文件 12.4 ISAM文件和VSAM文件 12.4.1 ISAM文件 12.4.2 VSAM文件 12.5 直接存取文件(散列文件) 12.6 多关键字文件 12.6.1 多重表文件 12.6.2 倒排文件 附录A 名词索引 附录B 函数索引 参考书目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值