当前位置: 首页 > ds >正文

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

公共头文件common.h

#define TRUE 1
#define FALSE 0// 定义节点数据类型
#define DATA_TYPE int

单链表C语言实现

SingleList.h

#pragma once#include "common.h"typedef struct Node
{DATA_TYPE data;struct Node *next;
} Node;Node *initList();void headInsert(Node *L, DATA_TYPE data);void tailInsert(Node *L, DATA_TYPE data);int contains(Node *L, DATA_TYPE data);int list_delete(Node *L, DATA_TYPE data);void printList(Node *L);void test_SingleList();int size(Node *L);

SingleList.c

#include <stdio.h>
#include <stdlib.h>#include "SingleList.h"// 头结点 链表的第一个节点 通常不存储实际的数据元素 用于简化操作、管理链表
// 首节点 头结点之后的第一个节点 链表中第一个存储实际数据的节点 
Node *initList()
{Node *head = malloc(sizeof(Node));head->data = 0;head->next = NULL;return head;
}// 头插法
void headInsert(Node *L, DATA_TYPE data)
{Node *node = malloc(sizeof(Node));node->data = data;node->next = L->next;L->next = node;L->data++;
}// 尾插法 需要遍历整个链表找到尾结点
void tailInsert(Node *L, DATA_TYPE data)
{Node *p_tmp = L;while (p_tmp->next != NULL) // 找到尾结点{p_tmp = p_tmp->next;}Node *node = malloc(sizeof(Node));node->data = data;node->next = NULL;p_tmp->next = node;L->data++;
}int contains(Node *L, DATA_TYPE data)
{Node *p_tmp = L;while (p_tmp->next != NULL && p_tmp->next->data != data){p_tmp = p_tmp->next;}if (p_tmp->next == NULL){return FALSE;}return TRUE;
}int list_delete(Node *L, DATA_TYPE data)
{Node *preNode = L;Node *node = L->next;while (node){if (node->data == data){preNode->next = node->next; // 删除节点free(node);                 // 释放节点占用内存L->data--;                  // 链表节点数减一return TRUE;}preNode = node; // 保存前一个节点指针node = node->next;}return FALSE;
}void printList(Node *L)
{Node *node = L->next;while (node){printf("%d -> ", node->data);node = node->next;}printf("NULL\n");
}int size(Node *L)
{return L->data;
}void test_SingleList()
{Node *head = initList();headInsert(head, 1);headInsert(head, 2);headInsert(head, 3);tailInsert(head, 4);tailInsert(head, 5);tailInsert(head, 6);printf("contains: %d\n", contains(head, 1));printf("contains: %d\n", contains(head, 6));printf("size: %d\n", size(head));printList(head);printf("\n");list_delete(head, 4);list_delete(head, 6);printf("size: %d\n", size(head));printList(head);
}

单链表Java实现

public class SingleList {private int size; // 保存节点个数private Node head;public SingleList() {head = new Node(0); // 头结点数据域保存节点个数 与 size等价}public void headInsert(int data) {Node node = new Node(data, head.next);head.next = node;head.data++;size++;}public void tailInsert(int data) {Node tmp = head;while (tmp.next != null) { // 找到尾结点tmp = tmp.next;}Node node = new Node(data);tmp.next = node;size++;head.data++;}public boolean contains(int data) {Node tmp = head;while (tmp.next != null && tmp.data != data) {tmp = tmp.next;}if (tmp.next == null) {return false;}return true;}public boolean delete(int data) { // Java LinkedList包含节点前后引用Node preNode = head; // 保存删除节点的前一个节点Node node = head.next;while (node != null) {if (node.data == data) { // 要删除的节点preNode.next = node.next;size--;head.data--;return true;}preNode = node;node = node.next;}return false;}public void printList() {Node node = head.next;while (node != null) {System.out.print(node.data + " -> ");node = node.next;}}public int size() {
//        return size;return head.data;}/*** 单链表节点类*/private static class Node {int data;Node next;public Node(int data) {this.data = data;}public Node(int data, Node next) {this.data = data;this.next = next;}}public static void main(String[] args) {SingleList list = new SingleList();list.headInsert(1);list.headInsert(2);list.headInsert(3);list.tailInsert(4);list.tailInsert(5);list.tailInsert(6);System.out.println(list.contains(1));System.out.println(list.contains(6));System.out.println("size: " + list.size());list.printList();System.out.println();list.delete(4);list.delete(6);System.out.println("size: " + list.size());list.printList();}
}

循环单链表

LoopSingleList.h

#pragma once#include "common.h"typedef struct Node
{DATA_TYPE data;struct Node *next;
} Node;Node *initList();void headInsert(Node *L, DATA_TYPE data);void tailInsert(Node *L, DATA_TYPE data);int list_delete(Node *L, DATA_TYPE data);void printList(Node *L);int size(Node *L);void test_loop_singleList();

LoopSingleList.c

#include <stdio.h>
#include <stdlib.h>#include "LoopSingleList.h"Node *initList()
{Node *head = malloc(sizeof(Node));head->data = 0;head->next = head;return head;
}void headInsert(Node *L, DATA_TYPE data)
{Node *node = malloc(sizeof(Node));node->data = data;node->next = L->next;L->next = node;L->data++;
}void tailInsert(Node *L, DATA_TYPE data)
{Node *node = malloc(sizeof(Node));node->data = data;Node *head = L;while (head->next != L){head = head->next;}node->next = L;head->next = node;L->data++;
}int list_delete(Node *L, DATA_TYPE data)
{Node *preNode = L;Node *node = L->next;while (node != L){if (node->data == data){preNode->next = node->next;free(node);L->data--;return TRUE;}preNode = node;node = node->next;}return FALSE;
}void printList(Node *L)
{Node *node = L->next;while (node != L){printf("%d -> ", node->data);node = node->next;}printf("(首节点)%d", node->next->data);
}int size(Node *L)
{return L->data;
}void test_loop_singleList()
{Node *head = initList();headInsert(head, 1);headInsert(head, 2);headInsert(head, 3);tailInsert(head, 4);tailInsert(head, 5);tailInsert(head, 6);printf("size: %d\n", size(head));printList(head);printf("\n");list_delete(head, 4);list_delete(head, 6);printf("size: %d\n", size(head));printList(head);
}

双链表

DoubleList.h

#include "common.h"typedef struct Node
{DATA_TYPE data;struct Node *pre;struct Node *next;
} Node;Node *initList();void headInsert(Node *L, DATA_TYPE data);void tailInsert(Node *L, DATA_TYPE data);int list_delete(Node *L, DATA_TYPE data);void printList(Node *L);int size(Node *L);void test_double_list();

DoubleList.c

#include <stdio.h>
#include <stdlib.h>#include "DoubleList.h"Node *initList()
{Node *head = malloc(sizeof(Node));head->data = 0;head->pre = NULL;head->next = NULL;return head;
}void headInsert(Node *L, DATA_TYPE data)
{Node *node = malloc(sizeof(Node));node->data = data;node->pre = L;node->next = L->next;if (L->next){L->next->pre = node;L->next = node;}else // 首次插入 L->next=NULL{L->next = node;}L->data++;
}void tailInsert(Node *L, DATA_TYPE data)
{Node *tail = L;while (tail->next){tail = tail->next;}Node *node = malloc(sizeof(Node));node->data = data;node->pre = tail;node->next = tail->next; // NULLtail->next = node;L->data++;
}int list_delete(Node *L, DATA_TYPE data)
{Node *head = L->next;while (head){if (head->data == data){if (head->next) // 如果不是尾结点{head->next->pre = head->pre;}head->pre->next = head->next;free(head);L->data--;return TRUE;}head = head->next;}return FALSE;
}void printList(Node *L)
{Node *node = L->next;while (node){printf("%d -> ", node->data);node = node->next;}printf("NULL\n");
}int size(Node *L)
{return L->data;
}void test_double_list()
{Node *head = initList();headInsert(head, 1);headInsert(head, 2);headInsert(head, 3);tailInsert(head, 4);tailInsert(head, 5);tailInsert(head, 6);printf("size: %d\n", size(head));printList(head);printf("\n");list_delete(head, 3); // 首节点list_delete(head, 4); // 中间节点list_delete(head, 6); // 尾结点printf("size: %d\n", size(head));printList(head);
}

循环双链表

LoopDoubleList.c

#include <stdio.h>
#include <stdlib.h>#include "DoubleList.h"Node *initList()
{Node *head = malloc(sizeof(Node));head->data = 0;head->pre = head;head->next = head;return head;
}void headInsert(Node *L, DATA_TYPE data)
{Node *node = malloc(sizeof(Node));node->data = data;node->pre = L;node->next = L->next;L->next->pre = node;L->next = node;L->data++;
}void tailInsert(Node *L, DATA_TYPE data)
{Node *tail = L;while (tail->next != L){tail = tail->next;}Node *node = malloc(sizeof(Node));node->data = data;node->pre = tail;node->next = tail->next;tail->next = node;L->data++;
}int list_delete(Node *L, DATA_TYPE data)
{Node *head = L->next;while (head != L){if (head->data == data){head->next->pre = head->pre;head->pre->next = head->next;free(head);L->data--;return TRUE;}head = head->next;}return FALSE;
}void printList(Node *L)
{Node *node = L->next;while (node != L){printf("%d -> ", node->data);node = node->next;}printf("NULL\n");
}int size(Node *L)
{return L->data;
}void test_double_list()
{Node *head = initList();headInsert(head, 1);headInsert(head, 2);headInsert(head, 3);tailInsert(head, 4);tailInsert(head, 5);tailInsert(head, 6);printf("size: %d\n", size(head));printList(head);list_delete(head, 3); // 首节点list_delete(head, 4); // 中间节点list_delete(head, 6); // 尾结点printf("size: %d\n", size(head));printList(head);
}

栈-链表实现

ListStack.h

#include "common.h"typedef struct Node
{DATA_TYPE data;struct Node *next;
} Node;Node *initStack();void push(Node *L, DATA_TYPE data);DATA_TYPE pop(Node *L);int is_empty(Node *L);void printStack(Node *L);void test_List_Stack();

ListStack.c

#include <stdio.h>
#include <stdlib.h>#include "listStack.h"Node *initStack()
{Node *head = malloc(sizeof(Node));head->data = 0;head->next = NULL;return head;
}void push(Node *L, DATA_TYPE data)
{Node *node = malloc(sizeof(Node));node->data = data;node->next = L->next;L->next = node;L->data++;
}DATA_TYPE pop(Node *L)
{if (L->next){Node *node = L->next;DATA_TYPE data = node->data;L->next = node->next;free(node); // 释放首节点内存L->data--;return data;}return 0;
}int is_empty(Node *L)
{return L->data == 0;
}void printStack(Node *L)
{Node *head = L->next;while (head){printf("%d -> ", head->data);head = head->next;}printf("NULL\n");
}void test_List_Stack()
{Node *stack = initStack();printf("is_empty: %d\n", is_empty(stack));push(stack, 1);push(stack, 2);push(stack, 3);push(stack, 4);printf("is_empty: %d\n", is_empty(stack));printStack(stack);pop(stack);printStack(stack);
}

栈-数组实现

ArrayStack.h

#include "common.h"void initStack();void push(DATA_TYPE data);DATA_TYPE pop();DATA_TYPE top();int is_empty();void printStack();void destroy_stack();void test_Array_Stack();

ArrayStack.c

#include <stdio.h>
#include <stdlib.h>#include "ArrayStack.h"static size_t size;      // 栈大小
static DATA_TYPE *stack; // 数组表示
static int index = -1;   // 栈顶指针void initStack(size_t stack_size)
{size = stack_size;stack = malloc(sizeof(DATA_TYPE) * size);
}void push(DATA_TYPE data)
{stack[++index] = data;
}DATA_TYPE pop()
{if (is_empty()){perror("空栈...\n");exit(1);}return stack[index--];
}DATA_TYPE top()
{return stack[index];
}int is_empty()
{return index == -1;
}void printStack()
{for (int i = index; i >= 0; i--){printf("%d ", stack[i]);}printf("\n");
}void destroy_stack()
{size = 0;free(stack);stack = NULL;
}void test_Array_Stack()
{initStack(10);printf("is_empty: %d\n", is_empty());push(1);push(2);push(3);push(4);printf("is_empty: %d\n", is_empty());printStack();printf("pop: %d\n", pop());printf("top: %d\n", top());printStack();destroy_stack();
}

队列-双链表实现

ListQueue.h

#pragma once#include "common.h"typedef struct Node
{DATA_TYPE data;struct Node *pre;struct Node *next;
} Node;Node *initQueue();void enQueue(Node *L, DATA_TYPE data);void deQueue(Node *L);void printQueue(Node *L);void test_List_Queue();

ListQueue.c

#include <stdio.h>
#include <stdlib.h>#include "ListQueue.h"Node *initQueue()
{Node *head = malloc(sizeof(Node));head->data = 0;head->pre = NULL;head->next = NULL;return head;
}void enQueue(Node *L, DATA_TYPE data)
{Node *head = L;while (head->next){head = head->next;}Node *node = malloc(sizeof(Node));node->data = data;node->pre = head;node->next = head->next;head->next = node;L->data++;
}void deQueue(Node *L)
{Node *node = L->next;L->next = node->next;node->next->pre = L;free(node);L->data--;
}void printQueue(Node *L)
{Node *node = L;while (node->next){printf("%d <- ", node->next->data);node = node->next;}printf("NULL\n");
}void test_List_Queue()
{Node *head = initQueue();enQueue(head, 1);enQueue(head, 2);enQueue(head, 3);enQueue(head, 4);printQueue(head);deQueue(head);deQueue(head);printQueue(head);
}

循环队列

ArrayCircularQueue.h

#include <stdlib.h>#include "common.h"typedef struct Queue
{DATA_TYPE *data;int front;int rear;
} Queue;Queue *initQueue(size_t size);void enQueue(Queue *Q, DATA_TYPE value);DATA_TYPE deQueue(Queue *Q);int isFull(Queue* Q);int isEmpty(Queue* Q);void printQueue(Queue *Q);void test_Array_Queue();

ArrayCircularQueue.c

#include <stdio.h>
#include <stdlib.h>#include "ArrayCircularQueue.h"/**
* 当普通队列的尾指针达到存储空间的末尾时,即使队列前方仍有空位,也无法继续存储新元素,这就是假溢出现象。
* 循环队列通过将存储空间视为环状来解决这一问题,使得当队尾指针到达末尾时,可以循环回到存储空间的开头继续存储元素。 
*/static size_t queue_size = -1;Queue *initQueue(size_t size)
{Queue *Q = malloc(sizeof(Queue));queue_size = size;Q->data = malloc(sizeof(DATA_TYPE) * size);Q->front = Q->rear = 0;return Q;
}void enQueue(Queue *Q, DATA_TYPE value)
{if (isFull(Q))return;Q->data[Q->rear] = value;Q->rear = (Q->rear + 1) % queue_size;
}DATA_TYPE deQueue(Queue *Q)
{if (isEmpty(Q)){perror("空队列...");exit(1);}DATA_TYPE val = Q->data[Q->front];Q->front = (Q->front + 1) % queue_size;return val;
}int isFull(Queue *Q)
{return (Q->rear + 1) % queue_size == Q->front;
}int isEmpty(Queue *Q)
{return Q->front == Q->rear; // 初始化时 队列为空
}void printQueue(Queue *Q)
{// 获取队列长度:队列中有多少个元素int len = (Q->rear - Q->front + queue_size) % queue_size;int index = Q->front;for (int i = 0; i < len; i++){printf("%d <- ", Q->data[index]);index = (index + 1) % queue_size;}printf("NULL\n");
}void test_Array_Queue()
{Queue *Q = initQueue(5);enQueue(Q, 1);enQueue(Q, 2);enQueue(Q, 3);enQueue(Q, 4);printf("isFull: %d\n", isFull(Q));enQueue(Q, 4);printf("isFull: %d\n", isFull(Q));printQueue(Q);deQueue(Q);deQueue(Q);printQueue(Q);
}

总结

栈:适用于需要后进先出的场景,如函数调用栈、表达式求值等。
队列:适用于需要先进先出的场景,如任务调度、消息队列等。
链表:适用于频繁插入和删除元素的场景,如链表实现的动态内存管理。
顺序表:一种以数组形式实现的线性结构,具有随机访问的特点。元素在内存中是连续存储的,支持快速的元素访问,但插入和删除操作需要移动多个元素。

http://www.xdnf.cn/news/3645.html

相关文章:

  • MATLAB图像加密案例
  • 状压 DP 详解
  • 揭开并发编程的面纱:从零开始构建 Java 阻塞队列
  • 【AI提示词】系统分析员
  • Redis怎么避免热点数据问题
  • 软件第三方测试:关键部分、意义、流程及方法全解析?
  • 轻量级在线Excel预览工具
  • PyTorch、Flash-Attn、Transformers与Triton技术全景解析+环境包
  • 第 13 届蓝桥杯 C++ 青少组省赛中 / 高级组 2022 年真题
  • Python全流程开发实战:基于IMAP协议安全下载个人Gmail邮箱内所有PDF附件
  • SQL语句练习 自学SQL网 在查询中使用表达式 统计
  • 组件通信-mitt
  • 数据结构之哈夫曼树
  • 【Hive入门】Hive性能调优之Join优化:深入解析MapJoin与Sort-Merge Join策略
  • 安装深度环境anaconda+cuda+cudnn+pycharm+qt+MVS
  • python 桌面程序开发简述及示例
  • 玩转Docker(一):基本概念
  • 觅知解析计费系统重构版在线支付卡密充值多解析接口免授权无后门源码扶风二开
  • Git 完整教程:初学者分步指南
  • 网工_IP协议
  • 前端面经-VUE3篇--vue3基础知识(一)插值表达式、ref、reactive
  • 2000-2020年全国各地级市资本存量测算数据(以2000年为基期)(含原始数据+计算过程+结果)
  • ASP.NET MVC​ 入门与提高指南七
  • 性能测试工具篇
  • 龙虎榜——20250430
  • 雅思写作--70个高频表达
  • CloudCompare中CCCoreLib模块内容
  • 数字智慧方案5981丨智慧农业解决方案(55页PPT)(文末有下载方式)
  • 机箱结构的EMC设计
  • 数字智慧方案6157丨智慧医疗建设方案(85页PPT)(文末有下载方式)