【无标题】

1. 基本概念定义

1.1 顺序表 (Sequential List)

顺序表是物理内存连续存储的数据结构,底层通常基于数组实现。其核心特点是:元素在内存中按逻辑顺序依次排列,每个元素的内存地址可通过“起始地址 + 索引×元素大小”直接计算,因此能通过索引快速定位任意元素,是线性表中最基础、最直观的实现方式之一。

1.2 链表 (Linked List)

链表是非连续存储的线性数据结构,由若干个“节点”通过指针(或引用)连接形成序列。每个节点包含两部分:

  • 数据域:存储节点的实际业务数据;
  • 指针域:存储下一个(或上一个,如双向链表)节点的内存地址,用于维护节点间的逻辑顺序。
    由于节点无需连续存储,链表的内存分配更加灵活,可根据数据量动态调整。

2. 核心特性对比

特性顺序表链表
存储方式连续内存空间,元素地址连续非连续内存空间,节点通过指针连接
内存分配支持静态分配(大小固定)或动态一次性分配(初始化时申请整块内存)动态按需分配,新增节点时才单独申请内存
访问方式随机访问,通过索引直接定位(如 a[i]),无需遍历顺序访问,必须从表头(头节点)开始遍历,无法直接跳转到目标节点
插入/删除效率需移动目标位置前后的元素(例如在中间插入时,需后移后续所有元素),平均时间复杂度 O(n)已知目标节点位置时,仅需修改指针指向(无需移动元素),时间复杂度 O(1)

3. 优缺点分析

3.1 顺序表的优缺点

优点
  1. 随机访问高效
  2. 缓存友好
  3. 空间效率高
缺点
  1. 大小固定(静态分配)
  2. 插入/删除低效
  3. 内存要求高
  4. 内存浪费

3.2 链表的优缺点

优点
  1. 动态大小
  2. 插入/删除高效
  3. 内存利用率高
缺点
  1. 随机访问低效
  2. 空间开销大
  3. 缓存不友好

4. 适用场景

4.1 顺序表适用场景

  • 频繁随机访问的场景
  • 对访问速度要求高的场景

4.2 链表适用场景

  • 频繁插入/删除的场景
  • 内存资源有限的场景
    双向链表
    在这里插入图片描述
    栈的操作
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define MAX 100
//栈结构体定义 
typedef struct stack{
	int data[MAX];
	int top;
	int maxlen;
}Stack,*Stack_p;
//创建堆栈  
Stack_p create(){
	Stack_p stack=(Stack_p)malloc(sizeof(Stack));
	if(NULL!=stack){
		stack->maxlen=MAX;
		memset(stack->data,0,sizeof(stack->data));
		stack->top=-1;
	}
	return stack;
}
//判满 
bool is_full(Stack_p stack){
	return stack->top+1==stack->maxlen;
}
//判空 
bool is_empty(Stack_p stack){
	return stack->top==-1;
}
//压栈 
bool push_stack(Stack_p stack,int value){
	if(NULL==stack||is_full(stack)) return false;
	stack->data[++stack->top]=value;
}
//出栈 
bool pop_stack(Stack_p stack){
	if(NULL==stack||is_empty(stack)) return false;
	stack->top--;
	return true;
}
//打印栈 
bool print_stack(Stack_p stack){
	printf("--------------------------------\n");
	for(int i=stack->top;i>=0;i--) printf("%d ",stack->data[i]);
	putchar(10);
	printf("--------------------------------\n");
}
//栈的销毁
bool destroy_stack(Stack_p *stack){
	if(NULL==*stack) return false;
	free(*stack);
	*stack=NULL;
	return true;
}
int main(int argc,const char *argv[]){
	//创建栈 
	Stack_p stack=create();
	//压栈 
	for(int i=1;i<=5;i++) push_stack(stack,i);
	printf("压栈后还剩%d个元素:\n",stack->top+1);
	print_stack(stack); 
	//弹栈
	for(int i=1;i<=4;i++){
		pop_stack(stack);
		printf("弹栈后还剩%d个元素:\n",stack->top+1);
		print_stack(stack);
	}
	destroy_stack(&stack);
	if(NULL==stack) printf("销毁后为NULL\n");
	else{
		printf("销毁后还剩下%d个元素\n",stack->top+1);
		print_stack(stack);
	} 
	print_stack(stack);
	return 0;
} 

在这里插入图片描述
双向循环链表操作

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define INF 0x7fffffff
//双向链表结构体定义 
typedef struct node{
	union{
		int len;
		int data;
	};
	struct node *pre,*next;
}Node,*Next;
//创建有头节点的双向链表 ,返回指针 
Next create_h(){
	Next L=(Next)malloc(sizeof(Node));
	if(NULL!=L){
		L->len=0;
		L->next=L;
		L->pre=L; 
	}
	return L;
}
//创建值为datd的双向链表节点 
Next create_n(int data){
	Next node=(Next)malloc(sizeof(Node));
	if(NULL!=node){
		node->data=data;
		node->next=NULL;
		node->pre=NULL; 
	}
	return node;
}
//打印双向链表,输完后自动换行 
void print(Next L){
	if(NULL!=L){
		Next p=L->next;
		while(p!=L){
			printf("%d ",p->data);
			p=p->next;
		}
		putchar(10);
	}
}
//头插法插入值为data的节点 
bool insert_h(Next L,int data){
	if(NULL==L) return false;
	Next p=create_n(data);
	if(NULL==p) return false;
	
	p->pre=L;p->next=L->next;
	L->next=p;
	p->next->pre=p;
	L->len++;
	return true; 
}
//判空 
bool isEmpty(Next L){
	if(NULL==L) return true;
	return L==L->next;
}
//从头开始删除一个节点 
bool delete_h(Next L){
	if(NULL==L||L==L->next) return false;
	
	Next p=L->next;
	p->next->pre=L;
	L->next=p->next; 
	free(p);
	return true;
}
//在尾节点插入一个值为value的节点 
bool insert_b(Next L,int value){
	if(NULL==L) return false;
	Next p=L;
	while(p->next!=L) p=p->next;
	Next node=create_n(value);
	if(NULL==node) return false;
	
	L->len++;
	node->next=p->next;
	node->pre=p;
	p->next=node;
	return true;;
}
//删除尾节点 
bool delete_b(Next L){
	if(NULL==L||L==L->next) return false;
	
	Next p=L;
	while(p->next->next!=L) p=p->next;
	
	free(p->next);
	p->next=L;
	L->len--;
	return true;
}
int main(int argc,const char *argv[]){
	//创建单链表 
	Next L=create_h();
	//头插法插入10个值为i的节点 
	printf("头插法\n");
	for(int i=1;i<=8;i++) insert_h(L,i);
	print(L);
	//头删法删除三个节点 
	printf("头删法:\n");
	delete_h(L);delete_h(L);delete_h(L);
	print(L);
	//尾插法插入值为-1,-2两个节点 
	printf("尾插法:\n");
	insert_b(L,-1);insert_b(L,-2);
	print(L);
	//尾删法删除两个尾节点 
	printf("尾删法:\n");
	delete_b(L),delete_b(L);
	print(L);
	return 0;
} 

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值