栈
stack.c
#include "stack.h"
//创建栈
stack_p creat_stack()
{
stack_p H=(stack_p)malloc(sizeof(stack));
if(H==NULL)
{
printf("空间申请失败\n");
return NULL;
}
H->top=-1;
bzero(H,sizeof(stack));
return H;
}
//将数据压入栈
void push_stack(stack_p H,int value)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
H->data[++(H->top)]=value;
}
//判空
int empty_stack(stack_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return -1;
}
return H->top==-1;
}
//判满
int full_stack(stack_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return -1;
}
return H->top==MAX-1;
}
//出栈
int pop_stack(stack_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return -1;
}
if(empty_stack(H))
{
printf("栈为空,不出栈\n");
return -1;
}
return H->data[H->top--];
}
//输出栈
void show_stack(stack_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
if(empty_stack(H))
{
printf("栈为空,不输出\n");
return;
}
stack_p p=H;
while(p->top>0)
{
printf("%d\n",p->data[p->top]);
p->top--;
}
}
//销毁栈
void del_stack(stack_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
if(empty_stack(H))
{
printf("栈为空\n");
return;
}
stack_p p=H;
while(p->top>0)
{
stack_p S=p->top--;
free(p->data[p->top]);
p=S;
}
}
stack.h
#ifndef __STACK_H__
#define __STACK_H__
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 7
typedef struct
{
int top;
int data[MAX];
}stack,*stack_p;
stack_p creat_stack();
void push_stack(stack_p,int);
int empty_stack(stack_p);
int full_stack(stack_p);
int pop_stack(stack_p);
void show_stack(stack_p);
void del_stack(stack_p);
#endif
main.c
#include "stack.h"
int main()
{
stack_p H=creat_stack();
push_stack(H,1);
push_stack(H,2);
push_stack(H,3);
push_stack(H,4);
push_stack(H,5);
show_stack(H);
return 0;
}
双向循环链表
main.c
#include "double.h"
int main()
{
node_p H=create_link();
insert_head(H,3);
insert_head(H,2);
insert_head(H,1);
show_link(H);
putchar(10);
del_pos(H,2);
show_link(H);
/*putchar(10);
insert_pos(H,3,4);
show_link(H);
insert_pos(H,5,7);*/
return 0;
}
double.c
#include "double.h"
//创建头节点
node_p create_link()
{
node_p H=(node_p)malloc(sizeof(node));
if(H==NULL)
{
printf("空间申请失败\n");
return NULL;
}
H->len=0;
H->pre=H;
H->next=H;
return H;
}
//创建节点
node_p create_node(int value)
{
node_p new=(node_p)malloc(sizeof(node));
if(new==NULL)
{
printf("节点空间申请失败\n");
return NULL;
}
new->data=value;
new->pre=new;
new->next=new;
return new;
}
//判空
int empty(node_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return -1;
}
return H->next==H;
}
//头增加
void insert_head(node_p H,int value)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
node_p new=create_node(value);
new->next=H->next;
new->pre=H;
H->next=new;
new->next->pre=new;
}
//尾部删除
void del_tail(node_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
if(empty(H))
{
printf("链表为空,不用删除\n");
return;
}
node_p p=H;
while(p->next!=H)
{
p=p->next;
}
p->pre->next=p->next;
p->next->pre=p->pre;
}
//输出
void show_link(node_p H)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
if(empty(H))
{
printf("链表为空,不输出\n");
return;
}
node_p p=H->next;
while(p!=H)
{
printf("%d\n",p->data);
p=p->next;
}
}
//按位置添加
void insert_pos(node_p H,int pos,int value)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
node_p p=H->next;
int i;
for(i=1;i<pos-1;i++)
{
if(p==NULL)
{
printf("插入的位置不合理\n");
return;
}
}
if(p==NULL)
{
printf("插入的位置不合理\n");
return;
}
node_p new=create_node(value);
new->next=p->next;
new->pre=p;
p->next=new;
new->next->pre=new;
}
//按位置删除
void del_pos(node_p H,int pos)
{
if(H==NULL)
{
printf("入参为空,请检查\n");
return;
}
if(empty(H))
{
printf("链表为空,不输出\n");
return;
}
int i;
node_p p=H;
for(i=0;i<pos;i++,p=p->next)
{
if(p==NULL)
{
printf("删除的位置不合理\n");
return;
}
}
if(p==NULL)
{
printf("插入的位置不合理\n");
return;
}
p->next->pre=p->pre;
p->pre->next=p->next;
free(p);
}
double.h
#ifndef __DOUBLE_H__
#define __DOUBLE_H__
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node
{
union
{
int len;
int data;
};
struct node *pre;
struct node *next;
}node,*node_p;
node_p create_link();
node_p create_node(int);
int empty(node_p);
void insert_head(node_p,int);
void del_tail(node_p);
void show_link(node_p);
void insert_pos(node_p,int,int);
void del_pos(node_p,int);
#endif
master@m
- 总结顺序表和链表的区别和优缺点。
-
1. 顺序表
- 优点:随机访问效率极高(O (1)),适合频繁查询;存储密度高(无指针开销);实现简单,不易出错。
- 缺点:插入 / 删除效率低(头部 / 中间需移动元素,O (n));动态扩容有拷贝开销,可能浪费内存;静态场景下容量固定,易溢出或闲置。
-
2. 链表
- 优点:插入 / 删除效率高(已知前驱 / 后继时仅改指针,O (1));容量动态灵活,无需提前分配;可利用零散内存空间。
- 缺点:无法随机访问(查询需遍历,O (n));存储密度低(指针占额外内存);实现复杂(易出现野指针、内存泄漏);缓存命中率低。
-
对比维度 顺序表(Sequential List) 链表(Linked List) 存储方式 连续内存空间(数据元素按顺序依次存储) 非连续内存空间(每个节点含数据 + 指针,节点间通过指针连接) 数据访问方式 随机访问(通过下标 i
直接定位,时间复杂度O(1)
)顺序访问(需从表头 / 表尾遍历到目标节点,时间复杂度 O(n)
)元素逻辑关系维护 靠内存地址的连续性维护(无需额外空间存储关系) 靠指针 / 引用维护(每个节点需额外存储 1~2 个指针,消耗内存) 容量特性 静态容量(初始化时固定大小)或动态扩容(需拷贝旧数据) 动态容量(按需申请 / 释放节点,无需提前分配固定空间) 数据元素类型限制 通常存储同类型数据(数组特性决定) 可存储同类型或自定义结构体数据(节点可灵活封装)