竞赛常考的知识点大总结(一)基本数据结构

链表

链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据部分和一个或多个指向其他节点的指针。链表中的节点可以动态地添加或删除,而不需要移动其他节点,这使得链表在插入和删除操作上非常高效。

特点:

1.动态大小:链表的大小不是固定的,可以根据需要动态地增加或减少。

2.随机访问困难:链表不支持随机访问,访问链表中的元素需要从头开始遍历。

3.插入和删除效率高:在链表的任何位置插入或删除元素只需要修改指针,不需要移动其他元素。

4.内存利用率高:链表不需要连续的内存空间,可以充分利用零碎的内存空间。

常见用法:

1.实现栈和队列:链表可以用来实现后进先出(LIFO)的栈和先进先出(FIFO)的队列。

2.动态数组:链表可以作为动态数组的底层实现,提供动态大小的数组。

3.哈希表的链地址法:在哈希表中,当多个元素哈希到同一个位置时,可以使用链表来解决冲突。

4.图的邻接表:在图论中,链表可以用来表示图的邻接表,存储图中顶点的邻接点。

经典C语言例题:

题目: 编写一个函数,将两个有序链表合并为一个新的有序链表,并返回新链表的头指针。

示例代码:

#include <stdio.h>
#include <stdlib.h>
 
// 定义链表节点结构体
struct ListNode {
    int val;
    struct ListNode *next;
};
 
// 创建新节点
struct ListNode* createNode(int val) {
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;
    return newNode;
}
 
// 合并两个有序链表
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    // 创建一个虚拟头节点
    struct ListNode dummyHead = {0, NULL};
    struct ListNode* current = &dummyHead;
 
    while (l1 != NULL && l2 != NULL) {
        if (l1->val < l2->val) {
            current->next = l1;
            l1 = l1->next;
        } else {
            current->next = l2;
            l2 = l2->next;
        }
        current = current->next;
    }
 
    // 将剩余的节点接到新链表的末尾---两个链表可能长度不一样,所以再两两一一对比后会有冗余 
    current->next = (l1 != NULL) ? l1 : l2;
 
    // 返回新链表的头指针
    return dummyHead.next;
}
 
// 打印链表
void printList(struct ListNode* head) {
    while (head != NULL) {
        printf("%d -> ", head->val);
        head = head->next;
    }
    printf("NULL\n");
}
 
// 释放链表
void freeList(struct ListNode* head) {
    struct ListNode* current = head;
    while (current != NULL) {
        struct ListNode* next = current->next;
        free(current);
        current = next;
    }
}
 
int main() {
    // 创建两个有序链表
    struct ListNode* list1 = createNode(1);
    list1->next = createNode(2);
    list1->next->next = createNode(4);
    list1->next->next->next = createNode(1);
 
    struct ListNode* list2 = createNode(1);
    list2->next = createNode(3);
    list2->next->next = createNode(4);
 
    // 合并链表
    struct ListNode* mergedList = mergeTwoLists(list1, list2);
 
    // 打印合并后的链表
    printList(mergedList);
 
    // 释放链表
    freeList(mergedList);
 
    return 0;
}

例题分析:

1.创建新节点:使用createNode函数创建新节点,并分配内存。

2.合并链表mergeTwoLists函数接受两个有序链表的头指针,使用一个虚拟头节点来简化边界条件的处理。

3.比较和连接:遍历两个链表,比较当前节点的值,将较小的节点连接到新链表上。

4.处理剩余节点:当一个链表遍历结束后,将另一个链表的剩余部分直接连接到新链表的末尾。

5.返回新链表:返回新链表的头指针。

6.打印和释放链表:在main函数中创建链表,调用mergeTwoLists函数合并链表,打印合并后的链表,并在最后释放链表占用的内存。

这个例题展示了链表的基本操作,包括创建节点、遍历、比较、连接和释放链表。通过这个例子,可以更好地理解链表的工作原理和操作方法。

======================================================================================================

队列

队列是一种先进先出(FIFO, First-In-First-Out)的数据结构,它只允许在队列的尾部(back)进行插入操作,在队列的头部(front)进行删除操作。队列常用于任务调度、消息队列、打印队列等场景。

特点:

1.先进先出:队列的元素按照进入队列的顺序进行处理,最先入队的元素将最先出队。

2.后进后出:与栈(后进先出)相对,队列不支持在任意位置插入或删除元素。

3.动态数组:队列通常使用动态数组或链表实现,以支持动态大小调整。

4.线程安全:在多线程环境中,队列需要实现线程同步机制,以保证数据的一致性和安全性。

常见用法:

1.任务调度:操作系统使用队列来管理任务的执行顺序。

2.消息队列:在分布式系统中,消息队列用于不同服务或进程之间的通信。

3.打印队列:计算机打印任务通常存储在打印队列中,按照请求顺序进行打印。

4.缓冲区管理:队列可以作为缓冲区,用于存储数据流,如网络数据包的接收和发送。

经典C语言例题:

题目: 编写一个函数,实现队列的基本操作,包括入队(enqueue)和出队(dequeue)。

示例代码:

#include <stdio.h>
#include <stdlib.h>

// 定义队列节点结构体
struct QueueNode {
    int data;
    struct QueueNode* next;
};

// 定义队列结构体
struct Queue {
    struct QueueNode* front;
    struct QueueNode* rear;
};

// 创建新队列节点
struct QueueNode* createQueueNode(int data) {
    struct QueueNode* newNode = (struct QueueNode*)malloc(sizeof(struct QueueNode));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 创建新队列
struct Queue* createQueue() {
    struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
    queue->front = NULL;
    queue->rear = NULL;
    return queue;
}

// 入队操作
void enqueue(struct Queue* queue, int data) {
    struct QueueNode* newNode = createQueueNode(data);
    if (queue->rear == NULL) {
        queue->front = newNode;
    } else {
        queue->rear->next = newNode;
    }
    queue->rear = newNode;
}

// 出队操作
int dequeue(struct Queue* queue) {
    if (queue->front == NULL) {
        printf("Queue is empty\n");
        return -1; // 返回-1表示队列为空
    }
    struct QueueNode* temp = queue->front;
    int data = temp->data;
    queue->front = queue->front->next;
    if (queue->front == NULL) {
        queue->rear = NULL;
    }
    free(temp);
    return data;
}

// 打印队列
void printQueue(struct Queue* queue) {
    struct QueueNode* current = queue->front;
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

// 释放队列
void freeQueue(struct Queue* queue) {
    while (queue->front != NULL) {
        dequeue(queue);
    }
    free(queue);
}

int main() {
    struct Queue* queue = createQueue();

    // 入队操作
    enqueue(queue, 1);
    enqueue(queue, 2);
    enqueue(queue, 3);

    // 打印队列
    printQueue(queue);

    // 出队操作
    int data = dequeue(queue);
    printf("Dequeued data: %d\n", data);

    // 再次打印队列
    printQueue(queue);

    // 释放队列
    freeQueue(queue);

    return 0;
}

例题分析:

1.创建队列节点:使用createQueueNode函数创建队列节点,并分配内存。

2.创建队列:使用createQueue函数创建队列结构体,并初始化队列的头指针和尾指针。

3.入队操作enqueue函数在队列的尾部插入新节点,如果队列为空,则新节点同时成为头节点。

4.出队操作dequeue函数从队列头部删除节点,并返回节点的数据。如果队列为空,则打印错误信息并返回-1。

5.打印队列printQueue函数遍历队列并打印所有节点的数据。

6.释放队列freeQueue函数遍历队列并释放所有节点的内存,最后释放队列结构体的内存。

这个例题展示了队列的基本操作,包括创建队列、入队和出队操作。通过这个例子,可以更好地理解队列的工作原理和操作方法。

======================================================================================================

优先队列

优先队列是一种特殊的队列,它允许在队列中的元素按照优先级进行排序,优先级高的元素可以优先出队。优先队列通常使用堆(heap)数据结构来实现,堆是一种近似完全二叉树的结构,并同时满足堆积性质:即子节点的键值或索引总是小于(或者大于)它的父节点。

特点:

1.优先级排序:优先队列中的元素根据优先级进行排序,优先级高的元素先出队。

2.动态调整:当元素的优先级发生变化时,优先队列可以动态地调整元素的位置,以保持优先级顺序。

3.堆实现:优先队列通常使用最大堆或最小堆来实现,最大堆中最大元素优先出队,最小堆中最小元素优先出队。

4.效率高:优先队列的插入和删除操作的时间复杂度通常是O(log n),其中n是队列中元素的数量。

常见用法:

1.任务调度:操作系统使用优先队列来管理任务的执行顺序,优先执行优先级高的任务。

2.网络数据包处理:在网络中,优先队列可以用来处理不同优先级的数据包。

3.事件驱动系统:在事件驱动的系统中,优先队列用于处理具有不同优先级的事件。

4.算法中的应用:如Dijkstra算法和Prim算法在寻找最短路径时使用优先队列来选择下一个要处理的顶点。

经典C语言例题:

题目: 使用最大堆实现一个优先队列,并提供插入(insert)和删除最大元素(deleteMax)操作。

示例代码:

#include <stdio.h>
#include <stdlib.h>

// 定义最大堆节点结构体
typedef struct MaxHeapNode {
    int key;
    int priority;
} MaxHeapNode;

// 定义最大堆结构体
typedef struct MaxHeap {
    int capacity;
    int size;
    MaxHeapNode** array;
} MaxHeap;

// 创建最大堆节点
MaxHeapNode* createMaxHeapNode(int key, int priority) {
    MaxHeapNode* newNode = (MaxHeapNode*)malloc(sizeof(MaxHeapNode));
    newNode->key = key;
    newNode->priority = priority;
    return newNode;
}

// 创建最大堆
MaxHeap* createMaxHeap(int capacity) {
    MaxHeap* maxHeap = (MaxHeap*)malloc(sizeof(MaxHeap));
    maxHeap->capacity = capacity;
    maxHeap->size = 0;
    maxHeap->array = (MaxHeapNode**)malloc(sizeof(MaxHeapNode*) * capacity);
    return maxHeap;
}

// 向最大堆中插入元素
void insert(MaxHeap* maxHeap, int key, int priority) {
    if (maxHeap->size == maxHeap->capacity) {
        printf("MaxHeap is full\n");
        return;
    }
    maxHeap->size++;
    int i = maxHeap->size - 1;
    maxHeap->array[i] = createMaxHeapNode(key, priority);
    while (i != 0 && maxHeap->array[i]->priority > maxHeap->array[(i - 1) / 2]->priority) {
        MaxHeapNode* temp = maxHeap->array[i];
        maxHeap->array[i] = maxHeap->array[(i - 1) / 2];
        maxHeap->array[(i - 1) / 2] = temp;
        i = (i - 1) / 2;
    }
}


// 堆化操作
void heapify(MaxHeap* maxHeap, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    if (left < maxHeap->size && maxHeap->array[left]->priority > maxHeap->array[largest]->priority) {
        largest = left;
    }

    if (right < maxHeap->size && maxHeap->array[right]->priority > maxHeap->array[largest]->priority) {
        largest = right;
    }

    if (largest != i) {
        MaxHeapNode* temp = maxHeap->array[i];
        maxHeap->array[i] = maxHeap->array[largest];
        maxHeap->array[largest] = temp;

        heapify(maxHeap, largest);
    }
}

// 删除最大元素
int deleteMax(MaxHeap* maxHeap) {
    if (maxHeap->size == 0) {
        printf("MaxHeap is empty\n");
        return -1;
    }
    int max = maxHeap->array[0]->key;
    maxHeap->array[0] = maxHeap->array[maxHeap->size - 1];
    maxHeap->size--;
    heapify(maxHeap, 0);
    return max;
}


// 打印最大堆
void printMaxHeap(MaxHeap* maxHeap) {
    for (int i = 0; i < maxHeap->size; i++) {
        printf("%d ", maxHeap->array[i]->key);
    }
    printf("\n");
}

// 释放最大堆
void freeMaxHeap(MaxHeap* maxHeap) {
    for (int i = 0; i < maxHeap->size; i++) {
        free(maxHeap->array[i]);
    }
    free(maxHeap->array);
    free(maxHeap);
}

int main() {
    MaxHeap* maxHeap = createMaxHeap(10);
    insert(maxHeap, 10, 3);
    insert(maxHeap, 20, 1);
    insert(maxHeap, 30, 5);
    insert(maxHeap, 40, 4);
    insert(maxHeap, 50, 2);

    printMaxHeap(maxHeap);

    int max = deleteMax(maxHeap);
    printf("Deleted max element: %d\n", max);

    printMaxHeap(maxHeap);

    freeMaxHeap(maxHeap);
    return 0;
}

例题分析:

1.创建最大堆节点:使用createMaxHeapNode函数创建最大堆节点,并分配内存。

2.创建最大堆:使用createMaxHeap函数创建最大堆结构体,并初始化容量、大小和数组。

3.插入操作insert函数向最大堆中插入新元素,首先检查堆是否已满,然后将新元素添加到堆的末尾,并通过上浮操作(heapify)来维护最大堆的性质。

4.删除最大元素deleteMax函数移除并返回最大元素,首先检查堆是否为空,然后将堆的最后一个元素移动到根节点,并通过下沉操作(heapify)来维护最大堆的性质。

5.打印最大堆printMaxHeap函数遍历并打印最大堆中的所有元素。

6.释放最大堆freeMaxHeap函数释放最大堆占用的内存。

这个例题展示了最大堆的实现和操作,包括插入和删除最大元素。通过这个例子,可以更好地理解优先队列的工作原理和操作方法。

======================================================================================================

栈是一种后进先出(LIFO, Last-In-First-Out)的数据结构,它只允许在栈的顶部(top)进行插入和删除操作。栈常用于表达式求值、函数调用、括号匹配、深度优先搜索等场景。

特点:

1.后进先出:栈的元素按照进入栈的顺序进行处理,最后进入的元素将最先出栈。

2.动态数组:栈通常使用动态数组或链表实现,以支持动态大小调整。

3.线程安全:在多线程环境中,栈需要实现线程同步机制,以保证数据的一致性和安全性。

常见用法:

1.函数调用:在程序执行过程中,函数调用的返回地址和参数通常存储在栈中。

2.表达式求值:编译器使用栈来计算数学表达式的值,如逆波兰表示法(RPN)。

3.括号匹配:栈可以用来检查表达式中的括号是否正确匹配。

4.深度优先搜索:在图论中,栈可以用来实现深度优先搜索算法。

经典C语言例题:

题目: 编写一个函数,实现栈的基本操作,包括入栈(push)、出栈(pop)和打印栈顶元素(peek)。

示例代码:

#include <stdio.h>
#include <stdlib.h>

// 定义栈节点结构体
struct StackNode {
    int data;
    struct StackNode* next;
};

// 定义栈结构体
struct Stack {
    struct StackNode* top;
    int size;
};

// 创建新栈节点
struct StackNode* createStackNode(int data) {
    struct StackNode* newNode = (struct StackNode*)malloc(sizeof(struct StackNode));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 创建新栈
struct Stack* createStack() {
    struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->top = NULL;
    stack->size = 0;
    return stack;
}

// 入栈操作
void push(struct Stack* stack, int data) {
    struct StackNode* newNode = createStackNode(data);
    newNode->next = stack->top;
    stack->top = newNode;
    stack->size++;
}

// 出栈操作
int pop(struct Stack* stack) {
    if (stack->top == NULL) {
        printf("Stack is empty\n");
        return -1; // 返回-1表示栈为空
     }
    struct StackNode* temp = stack->top;
    int data = temp->data;
    stack->top = stack->top->next;
    stack->size--;
    free(temp);
    return data;
}

// 打印栈顶元素
int peek(struct Stack* stack) {
    if (stack->top == NULL) {
        printf("Stack is empty\n");
        return -1; // 返回-1表示栈为空
     }
    return stack->top->data;
}

// 打印栈
void printStack(struct Stack* stack) {
    struct StackNode* current = stack->top;
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
     }
    printf("NULL\n");
}

// 释放栈
void freeStack(struct Stack* stack) {
    while (stack->top != NULL) {
        pop(stack);
     }
    free(stack);
}

int main() {
    struct Stack* stack = createStack();

    // 入栈操作
    push(stack, 1);
    push(stack, 2);
    push(stack, 3);

     // 打印栈顶元素
    printf("Top element: %d\n", peek(stack));

     // 出栈操作
    int data = pop(stack);
    printf("Popped element: %d\n", data);

     // 再次打印栈
    printStack(stack);

     // 释放栈
    freeStack(stack);

     return 0;
}

例题分析:

1.创建栈节点:使用createStackNode函数创建栈节点,并分配内存。

2.创建栈:使用createStack函数创建栈结构体,并初始化栈顶指针和大小。

3.入栈操作push函数在栈的顶部插入新节点,并更新栈顶指针。

4.出栈操作pop函数从栈顶部删除节点,并返回节点的数据。如果栈为空,则打印错误信息并返回-1。

5.打印栈顶元素peek函数返回栈顶元素的数据,但不移除它。如果栈为空,则打印错误信息并返回-1。

6.打印栈printStack函数遍历栈并打印所有节点的数据。

7.释放栈freeStack函数遍历栈并释放所有节点的内存,最后释放栈结构体的内存。

这个例题展示了栈的基本操作,包括创建栈、入栈和出栈操作。通过这个例子,可以更好地理解栈的工作原理和操作方法。

======================================================================================================

哈希

哈希(Hashing)是一种将任意长度的数据(通常是字符串)转换为固定长度数据的技术。哈希函数(Hash Function)是实现哈希的关键,它将输入数据映射到一个固定大小的哈希表(Hash Table)中。哈希表通常是一个数组,每个元素称为一个“桶”(Bucket),用于存储哈希值对应的元素。

哈希的特点:

1.固定长度:哈希函数的输出是一个固定长度的值,通常是一个整数。

2.快速查找:哈希表允许快速查找、插入和删除操作,平均时间复杂度为O(1)。

3.冲突处理:由于不同输入可能产生相同的哈希值,哈希表需要一种机制来处理这种冲突,如链地址法或开放寻址法。

4.不可逆性:哈希函数通常是单向的,即从哈希值很难或无法恢复原始数据。

5.抗碰撞性:好的哈希函数应该尽量减少不同输入产生相同哈希值的情况,即减少冲突。

常见用法:

1.数据存储:在数据库和文件系统中,哈希用于快速定位数据。

2.密码存储:在用户认证系统中,密码通常通过哈希函数存储,以提高安全性。

3.缓存:在Web应用中,哈希用于实现缓存机制,提高数据访问速度。

4.数据去重:在数据处理中,哈希用于快速检测重复数据。

5.数字签名:在数字签名和加密中,哈希用于生成数据的唯一指纹。

经典C语言例题:

题目:使用哈希表解决字符串去重问题。

示例代码

#include <stdio.h>
#include <string.h>
#include <malloc.h> 

#define TABLE_SIZE 1000

// 哈希函数
unsigned int hash(const char* str) {
    unsigned int hashval = 0;
    while (*str) {
          hashval = 31 * hashval + *str++;
     }
     return hashval % TABLE_SIZE;
}

// 哈希表结构
typedef struct HashNode {
    char* data;
    struct HashNode* next;
} HashNode;

// 哈希表
HashNode* hashTable[TABLE_SIZE];

// 初始化哈希表
void initHashTable() {
    for (int i = 0; i < TABLE_SIZE; i++) {
          hashTable[i] = NULL;
     }
}

// 插入字符串到哈希表
void insert(const char* str) {
    unsigned int key = hash(str);
    HashNode* node = (HashNode*)malloc(sizeof(HashNode));
     node->data = strdup(str);
     node->next = hashTable[key];
     hashTable[key] = node;
}

// 检查字符串是否已存在于哈希表
int search(const char* str) {
    unsigned int key = hash(str);
     HashNode* node = hashTable[key];
     while (node) {
          if (strcmp(node->data, str) == 0) {
               return 1; // 字符串已存在
          }
          node = node->next;
     }
     return 0; // 字符串不存在
}

int main() {
    initHashTable();
     insert("hello");
     insert("world");
     insert("hello");
     insert("c++");

     // 检查字符串是否已存在于哈希表
     printf("Is 'hello' in the hash table? %s\n", search("hello") ? "Yes" : "No");
     printf("Is 'c++' in the hash table? %s\n", search("c++") ? "Yes" : "No");

     // 清理哈希表
     for (int i = 0; i < TABLE_SIZE; i++) {
          HashNode* node = hashTable[i];
          while (node) {
               HashNode* temp = node;
               node = node->next;
               free(temp->data);
               free(temp);
          }
     }

     return 0;
}

例题分析:

1.哈希函数:定义了一个简单的哈希函数hash,它通过一个简单的乘法和加法操作将字符串转换为一个整数。

2.哈希表结构:定义了一个HashNode结构体,用于存储哈希表中的每个元素。

3.初始化哈希表initHashTable函数初始化一个大小为TABLE_SIZE的哈希表。

4.插入字符串insert函数将一个字符串插入到哈希表中。

5.搜索字符串search函数检查一个字符串是否已经存在于哈希表中。

6.主函数:在main函数中,初始化哈希表,插入几个字符串,然后检查这些字符串是否存在于哈希表中。最后,清理哈希表,释放所有分配的内存。

        这个例题展示了如何在C语言中使用哈希表来解决字符串去重问题。通过这个例子,可以更好地理解哈希在处理数据集合中的应用,以及如何使用哈希表来高效地解决问题。哈希表提供了一种快速查找和存储数据的方法,使得在大量数据中查找特定元素变得非常高效。

======================================================================================================

二叉树

二叉树是一种树形数据结构,它每个节点最多有两个子节点,通常子节点被称作“左子节点”和“右子节点”。二叉树的每个节点都包含一个值,以及对子节点的引用。

特点:

1.最多两个子节点:每个节点最多有两个子节点,分别称为左子节点和右子节点。

2.有序或无序:二叉树可以是有序的,也可以是无序的。在有序二叉树中,左子节点的值小于父节点的值,右子节点的值大于父节点的值。

3.递归定义:二叉树可以递归地定义为每个节点都是一棵二叉树。

4.遍历方式多样:二叉树可以通过前序、中序、后序和层次遍历等多种方式遍历。

常见用法:

1.二叉搜索树:用于快速检索、插入和删除操作。

2.:二叉堆是一种特殊的完全二叉树,用于实现优先队列。

3.二叉树遍历:用于实现各种算法,如深度优先搜索(DFS)和广度优先搜索(BFS)。

4.二叉树的序列化和反序列化:用于存储和传输二叉树结构。

5.表达式树:在编译器设计中,表达式树用于表示算术表达式。

经典C语言例题:

题目: 编写一个函数,实现二叉树的前序遍历。

示例代码:

#include <stdio.h>
#include <stdlib.h>

// 定义二叉树节点结构体
struct TreeNode {
    int val;
    struct TreeNode* left;
    struct TreeNode* right;
};

// 创建新二叉树节点
struct TreeNode* createNode(int val) {
    struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    newNode->val = val;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

// 二叉树的前序遍历
void preorderTraversal(struct TreeNode* root) {
    if (root == NULL) {
        return;
     }
     printf("%d ", root->val); // 访问根节点
     preorderTraversal(root->left); // 遍历左子树
     preorderTraversal(root->right); // 遍历右子树
}

// 释放二叉树
void freeTree(struct TreeNode* root) {
    if (root == NULL) {
         return;
     }
     freeTree(root->left);
     freeTree(root->right);
     free(root);
}

int main() {
     // 构建二叉树
     //        1
     //       / \
     //      2   3
     //     / \
     //    4   5
     struct TreeNode* root = createNode(1);
     root->left = createNode(2);
     root->right = createNode(3);
     root->left->left = createNode(4);
     root->left->right = createNode(5);

     // 前序遍历二叉树
     printf("Preorder traversal of the binary tree: ");
     preorderTraversal(root);
     printf("\n");

     // 释放二叉树
     freeTree(root);

     return 0;
}

例题分析:

1.创建二叉树节点:使用createNode函数创建二叉树节点,并分配内存。

2.二叉树的前序遍历preorderTraversal函数递归地访问每个节点,首先访问根节点,然后递归地访问左子树,最后递归地访问右子树。

3.打印前序遍历结果:在main函数中,构建了一个简单的二叉树,并调用preorderTraversal函数进行前序遍历,打印遍历结果。

4.释放二叉树freeTree函数递归地释放二叉树占用的内存,先释放左子树和右子树,最后释放根节点。

这个例题展示了二叉树的前序遍历操作,通过这个例子,可以更好地理解二叉树的遍历方法和递归的使用。在实际应用中,二叉树的遍历可以用于实现各种算法和数据处理任务。

  • 31
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值