如何用c语言设计和实现数据结构

如何用c语言设计和实现数据结构

如何用C语言设计和实现数据结构

使用C语言设计和实现数据结构的核心在于:理解数据结构的本质、选择合适的数据结构以及编写高效的代码。在C语言中,设计和实现数据结构需要掌握指针、动态内存分配以及结构体等关键技术。下面我们将详细介绍如何使用C语言设计和实现常见的数据结构,包括链表、栈、队列、树和图,并提供代码示例和性能优化建议。

一、链表

链表是一种线性数据结构,其中每个元素是一个节点,节点包含数据和一个指向下一个节点的指针。链表的主要优点是插入和删除操作非常高效。

1.1 单链表

单链表是链表的一种,每个节点包含一个数据和一个指向下一个节点的指针。

#include <stdio.h>

#include <stdlib.h>

// 定义节点结构

struct Node {

int data;

struct Node* next;

};

// 创建新节点

struct Node* createNode(int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->next = NULL;

return newNode;

}

// 插入节点到链表头部

void insertAtHead(struct Node head, int data) {

struct Node* newNode = createNode(data);

newNode->next = *head;

*head = newNode;

}

// 删除链表中的节点

void deleteNode(struct Node head, int key) {

struct Node* temp = *head;

struct Node* prev = NULL;

if (temp != NULL && temp->data == key) {

*head = temp->next;

free(temp);

return;

}

while (temp != NULL && temp->data != key) {

prev = temp;

temp = temp->next;

}

if (temp == NULL) return;

prev->next = temp->next;

free(temp);

}

// 打印链表

void printList(struct Node* head) {

while (head != NULL) {

printf("%d -> ", head->data);

head = head->next;

}

printf("NULLn");

}

int main() {

struct Node* head = NULL;

insertAtHead(&head, 1);

insertAtHead(&head, 2);

insertAtHead(&head, 3);

printList(head);

deleteNode(&head, 2);

printList(head);

return 0;

}

1.2 双链表

双链表是链表的另一种形式,每个节点包含两个指针,一个指向前一个节点,一个指向后一个节点。

#include <stdio.h>

#include <stdlib.h>

// 定义节点结构

struct Node {

int data;

struct Node* next;

struct Node* prev;

};

// 创建新节点

struct Node* createNode(int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->next = NULL;

newNode->prev = NULL;

return newNode;

}

// 插入节点到双链表头部

void insertAtHead(struct Node head, int data) {

struct Node* newNode = createNode(data);

newNode->next = *head;

if (*head != NULL) {

(*head)->prev = newNode;

}

*head = newNode;

}

// 删除双链表中的节点

void deleteNode(struct Node head, int key) {

struct Node* temp = *head;

while (temp != NULL && temp->data != key) {

temp = temp->next;

}

if (temp == NULL) return;

if (*head == temp) {

*head = temp->next;

}

if (temp->next != NULL) {

temp->next->prev = temp->prev;

}

if (temp->prev != NULL) {

temp->prev->next = temp->next;

}

free(temp);

}

// 打印双链表

void printList(struct Node* head) {

while (head != NULL) {

printf("%d <-> ", head->data);

head = head->next;

}

printf("NULLn");

}

int main() {

struct Node* head = NULL;

insertAtHead(&head, 1);

insertAtHead(&head, 2);

insertAtHead(&head, 3);

printList(head);

deleteNode(&head, 2);

printList(head);

return 0;

}

二、栈

栈是一种LIFO(后进先出)的数据结构,插入和删除操作仅在栈顶进行。栈的主要操作包括:压栈(push)、弹栈(pop)和查看栈顶元素(peek)。

2.1 使用数组实现栈

#include <stdio.h>

#include <stdlib.h>

#define MAX 1000

struct Stack {

int top;

int array[MAX];

};

// 创建栈

struct Stack* createStack() {

struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));

stack->top = -1;

return stack;

}

// 检查栈是否为空

int isEmpty(struct Stack* stack) {

return stack->top == -1;

}

// 压栈

void push(struct Stack* stack, int data) {

if (stack->top == MAX - 1) {

printf("Stack overflown");

return;

}

stack->array[++stack->top] = data;

}

// 弹栈

int pop(struct Stack* stack) {

if (isEmpty(stack)) {

printf("Stack underflown");

return -1;

}

return stack->array[stack->top--];

}

// 查看栈顶元素

int peek(struct Stack* stack) {

if (isEmpty(stack)) {

printf("Stack is emptyn");

return -1;

}

return stack->array[stack->top];

}

int main() {

struct Stack* stack = createStack();

push(stack, 1);

push(stack, 2);

push(stack, 3);

printf("Top element is %dn", peek(stack));

printf("Popped element is %dn", pop(stack));

printf("Top element is %dn", peek(stack));

return 0;

}

2.2 使用链表实现栈

#include <stdio.h>

#include <stdlib.h>

// 定义节点结构

struct Node {

int data;

struct Node* next;

};

// 创建栈顶节点

struct Node* createNode(int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->next = NULL;

return newNode;

}

// 检查栈是否为空

int isEmpty(struct Node* root) {

return !root;

}

// 压栈

void push(struct Node root, int data) {

struct Node* newNode = createNode(data);

newNode->next = *root;

*root = newNode;

printf("%d pushed to stackn", data);

}

// 弹栈

int pop(struct Node root) {

if (isEmpty(*root)) {

printf("Stack underflown");

return -1;

}

struct Node* temp = *root;

*root = (*root)->next;

int popped = temp->data;

free(temp);

return popped;

}

// 查看栈顶元素

int peek(struct Node* root) {

if (isEmpty(root)) {

printf("Stack is emptyn");

return -1;

}

return root->data;

}

int main() {

struct Node* root = NULL;

push(&root, 1);

push(&root, 2);

push(&root, 3);

printf("Top element is %dn", peek(root));

printf("Popped element is %dn", pop(&root));

printf("Top element is %dn", peek(root));

return 0;

}

三、队列

队列是一种FIFO(先进先出)的数据结构,插入操作在队尾进行,删除操作在队头进行。队列的主要操作包括:入队(enqueue)、出队(dequeue)和查看队头元素(front)。

3.1 使用数组实现队列

#include <stdio.h>

#include <stdlib.h>

#define MAX 1000

struct Queue {

int front, rear, size;

unsigned capacity;

int* array;

};

// 创建队列

struct Queue* createQueue(unsigned capacity) {

struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));

queue->capacity = capacity;

queue->front = queue->size = 0;

queue->rear = capacity - 1;

queue->array = (int*)malloc(queue->capacity * sizeof(int));

return queue;

}

// 检查队列是否已满

int isFull(struct Queue* queue) {

return queue->size == queue->capacity;

}

// 检查队列是否为空

int isEmpty(struct Queue* queue) {

return queue->size == 0;

}

// 入队

void enqueue(struct Queue* queue, int data) {

if (isFull(queue)) {

printf("Queue overflown");

return;

}

queue->rear = (queue->rear + 1) % queue->capacity;

queue->array[queue->rear] = data;

queue->size = queue->size + 1;

printf("%d enqueued to queuen", data);

}

// 出队

int dequeue(struct Queue* queue) {

if (isEmpty(queue)) {

printf("Queue underflown");

return -1;

}

int data = queue->array[queue->front];

queue->front = (queue->front + 1) % queue->capacity;

queue->size = queue->size - 1;

return data;

}

// 查看队头元素

int front(struct Queue* queue) {

if (isEmpty(queue)) {

printf("Queue is emptyn");

return -1;

}

return queue->array[queue->front];

}

int main() {

struct Queue* queue = createQueue(MAX);

enqueue(queue, 1);

enqueue(queue, 2);

enqueue(queue, 3);

printf("Front element is %dn", front(queue));

printf("Dequeued element is %dn", dequeue(queue));

printf("Front element is %dn", front(queue));

return 0;

}

3.2 使用链表实现队列

#include <stdio.h>

#include <stdlib.h>

// 定义节点结构

struct Node {

int data;

struct Node* next;

};

// 定义队列结构

struct Queue {

struct Node *front, *rear;

};

// 创建新节点

struct Node* createNode(int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->next = NULL;

return newNode;

}

// 创建队列

struct Queue* createQueue() {

struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));

queue->front = queue->rear = NULL;

return queue;

}

// 入队

void enqueue(struct Queue* queue, int data) {

struct Node* newNode = createNode(data);

if (queue->rear == NULL) {

queue->front = queue->rear = newNode;

printf("%d enqueued to queuen", data);

return;

}

queue->rear->next = newNode;

queue->rear = newNode;

printf("%d enqueued to queuen", data);

}

// 出队

int dequeue(struct Queue* queue) {

if (queue->front == NULL) {

printf("Queue underflown");

return -1;

}

struct Node* temp = queue->front;

queue->front = queue->front->next;

if (queue->front == NULL) {

queue->rear = NULL;

}

int data = temp->data;

free(temp);

return data;

}

// 查看队头元素

int front(struct Queue* queue) {

if (queue->front == NULL) {

printf("Queue is emptyn");

return -1;

}

return queue->front->data;

}

int main() {

struct Queue* queue = createQueue();

enqueue(queue, 1);

enqueue(queue, 2);

enqueue(queue, 3);

printf("Front element is %dn", front(queue));

printf("Dequeued element is %dn", dequeue(queue));

printf("Front element is %dn", front(queue));

return 0;

}

四、树

树是一种层次数据结构,由节点组成,其中每个节点包含数据和指向子节点的指针。树的常见类型包括二叉树、二叉搜索树、平衡树等。

4.1 二叉树

#include <stdio.h>

#include <stdlib.h>

// 定义节点结构

struct Node {

int data;

struct Node* left;

struct Node* right;

};

// 创建新节点

struct Node* createNode(int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->left = newNode->right = NULL;

return newNode;

}

// 前序遍历

void preOrder(struct Node* root) {

if (root != NULL) {

printf("%d ", root->data);

preOrder(root->left);

preOrder(root->right);

}

}

// 中序遍历

void inOrder(struct Node* root) {

if (root != NULL) {

inOrder(root->left);

printf("%d ", root->data);

inOrder(root->right);

}

}

// 后序遍历

void postOrder(struct Node* root) {

if (root != NULL) {

postOrder(root->left);

postOrder(root->right);

printf("%d ", root->data);

}

}

int main() {

struct Node* root = createNode(1);

root->left = createNode(2);

root->right = createNode(3);

root->left->left = createNode(4);

root->left->right = createNode(5);

printf("Preorder traversal: ");

preOrder(root);

printf("n");

printf("Inorder traversal: ");

inOrder(root);

printf("n");

printf("Postorder traversal: ");

postOrder(root);

printf("n");

return 0;

}

4.2 二叉搜索树

#include <stdio.h>

#include <stdlib.h>

// 定义节点结构

struct Node {

int data;

struct Node* left;

struct Node* right;

};

// 创建新节点

struct Node* createNode(int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->left = newNode->right = NULL;

return newNode;

}

// 插入节点到二叉搜索树

struct Node* insert(struct Node* node, int data) {

if (node == NULL) {

return createNode(data);

}

if (data < node->data) {

node->left = insert(node->left, data);

} else if (data > node->data) {

node->right = insert(node->right, data);

}

return node;

}

// 中序遍历

void inOrder(struct Node* root) {

if (root != NULL) {

inOrder(root->left);

printf("%d ", root->data);

inOrder(root->right);

}

}

// 查找节点

struct Node* search(struct Node* root, int data) {

if (root == NULL || root->data == data) {

return root;

}

if (data < root->data) {

return search(root->left, data);

}

return search(root->right, data);

}

int main() {

struct Node* root = NULL;

root = insert(root, 50);

insert(root, 30);

insert(root, 20);

insert(root, 40);

insert(root, 70);

insert(root, 60);

insert(root, 80);

printf("Inorder traversal: ");

inOrder(root);

printf("n");

struct Node* foundNode = search(root, 40);

if (foundNode != NULL) {

printf("Node found with value %dn", foundNode->data);

} else {

printf("Node not foundn");

}

return 0;

}

五、图

图是一种非线性数据结构,由顶点和边组成。图的常见表示方法包括邻接矩阵和邻接表。

5.1 邻接矩阵表示图

#include <stdio.h>

#include <stdlib.h>

#define V 5

// 打印图的邻接矩阵

void printGraph(int graph[V][V]) {

for (int i = 0; i < V; i++) {

for (int j = 0; j < V; j++) {

printf("%d ", graph[i][j]);

}

printf("n");

}

}

int main() {

int graph[V][V] = {

{0, 1, 1, 0, 0},

{1, 0, 0, 1, 1},

{1, 0, 0, 1, 0},

{0, 1, 1, 0, 1},

{0, 1, 0, 1, 0}

};

printf("Adjacency matrix of the graph:n");

printGraph(graph);

return 0;

}

5.2 邻接表表示图

#include <stdio.h>

#include <stdlib.h>

// 定义节点结构

struct Node {

int dest;

struct Node* next;

};

// 定义邻接表结构

struct AdjList {

相关问答FAQs:

1. 如何在C语言中创建一个链表数据结构?

在C语言中创建链表数据结构,可以先定义一个结构体用来表示链表的节点,该结构体包含一个数据字段和一个指向下一个节点的指针字段。然后,通过动态内存分配函数malloc来创建节点,并使用指针来连接节点,形成链表。

2. 如何在C语言中实现栈数据结构?

要在C语言中实现栈数据结构,可以使用数组或链表来存储栈元素。使用数组时,可以定义一个固定大小的数组,同时维护一个指向栈顶的指针,通过修改指针的位置来实现入栈和出栈操作。使用链表时,可以定义一个结构体表示栈节点,该结构体包含一个数据字段和一个指向下一个节点的指针字段,通过动态内存分配函数malloc来创建节点,并使用指针来连接节点,形成链表。

3. 如何在C语言中实现队列数据结构?

在C语言中实现队列数据结构,可以使用数组或链表来存储队列元素。使用数组时,可以定义一个固定大小的数组,同时维护一个指向队列头和尾的指针,通过修改指针的位置来实现入队和出队操作。使用链表时,可以定义一个结构体表示队列节点,该结构体包含一个数据字段和一个指向下一个节点的指针字段,通过动态内存分配函数malloc来创建节点,并使用指针来连接节点,形成链表。

原创文章,作者:Edit1,如若转载,请注明出处:https://docs.pingcode.com/baike/1096278

(0)
Edit1Edit1
上一篇 2024年8月29日 上午12:11
下一篇 2024年8月29日 上午12:11
免费注册
电话联系

4008001024

微信咨询
微信咨询
返回顶部