8.25作业
一、双向循环链表
#include "head.h"//创建结点
cir_dou_list_p create_node(int flag,int element)
{cir_dou_list_p node=(cir_dou_list_p)malloc(sizeof(cir_dou_list));if(node==NULL){printf("空间申请失败..\n");return NULL;}if(flag==1){node->len=0;}else if(flag==0){node->data=element;}else{printf("输入的flag不合理..\n");}node->next=node;node->prev=node;return node;
}//头插
void insert_head(cir_dou_list_p head,int element)
{if(head==NULL){printf("入参为空..\n");return;}cir_dou_list_p a=create_node(0,element);a->next=head->next;a->prev=head;head->next=a;if(a->next!=head){a->next->prev=a;}head->len++;
}//判空
int empty(cir_dou_list_p head)
{if(head==NULL){printf("入参为空..\n");return -1;}if(head->next==head){printf("双向链表为空..\n");return -2;}return 0;
}//尾插
void insert_rear(cir_dou_list_p head,int element)
{cir_dou_list_p a=head->next;while(a->next!=head){a=a->next;}cir_dou_list_p b=create_node(0,element);b->next=a->next;b->prev=a;a->next=b;head->len++;
}//任意位置插入
void insert_position(cir_dou_list_p head,int position,int element)
{if(head==NULL){printf("入参为空..\n");return;}if(position<1){printf("输入的位置不合理..\n");return;}cir_dou_list_p a=head;for(int i=0;i<position-1;i++,a=a->next){if(a->next==head){printf("输入的位置不合理..\n");return;}}if(a==head){printf("输入的位置不合理..\n");return;}cir_dou_list_p b=create_node(0,element);b->next=a->next;b->prev=a;a->next=b;if(b->next!=head){b->next->prev=b;}head->len++;
}//输出
void show_list(cir_dou_list_p head)
{if(empty(head)<0)return;cir_dou_list_p a=head->next;while(a!=head){printf("%d",a->data);if(a->next!=head)printf("<==>");a=a->next;}putchar(10);
}//头删
void delete_head(cir_dou_list_p head)
{if(empty(head)<0)return;cir_dou_list_p a=head->next;head->next=a->next;if(a->next->prev!=head){a->next->prev=head;}free(a);a=NULL;head->len--;
}//链表的逆置
void reverse_list(cir_dou_list_p head)
{if(empty(head)<0)return;cir_dou_list_p a=head->next;if(a->next==head){printf("只有一个节点,不用逆置..\n");return;}cir_dou_list_p p=a->next;cir_dou_list_p q=p;a->next=head;while(p!=head){p=p->next;q->next=head->next;q->prev=head;head->next=q;q->next->prev=q;q=p;}
}
二、栈
#include"head.h"struct zhan* create_zhan()
{struct zhan* a=(struct zhan*)malloc(sizeof(struct zhan));if(a==NULL){printf("空间申请失败..\n");return NULL;}bzero(a->data,sizeof(a->data));a->top=-1;return a;
}//入栈
void insert(struct zhan* a,int element)
{if(a==NULL) {printf("入参为空\n");return;}if(a->top<MAX){a->top++;a->data[a->top]=element;return;}printf("栈已满\n");
}//输出
void show(struct zhan* a)
{if(a==NULL||a->top==-1){printf("栈不存在或者栈已满..\n");return;}for(int i=a->top;i>=0;i--){printf("data[%d]=%d\n",i,a->data[i]);}
}void delete(struct zhan* a)
{if(a==NULL||a->top==-1){printf("栈不存在或者栈已满..\n");return;}if(a->top>-1){a->top--;}
}void destory(struct zhan** a)
{if(*a==NULL){printf("栈不存在..\n");return;}free(a);a=NULL;
}
三、顺序表和链表的区别
顺序表:空间利用率有浪费,无碎片
优点:无额外指针开销,每个元素仅存储数据本身,空间密度高(空间密度 = 数据占用空间 / 总占用空间)。- 缺点:静态顺序表:若元素数量远小于容量,会浪费大量连续内存;动态顺序表:扩容时会预留冗余空间(如 ArrayList 扩容为 1.5 倍),仍有潜在浪费;需申请 “连续的大块内存”,若内存中无足够连续空间,即使总空闲内存足够,也无法创建顺序表。
- 链表:空间利用率灵活,有碎片
- 缺点:离散存储会产生 “内存碎片”(大量小而无用的内存块),长期使用可能影响内存效率。每个节点需额外存储指针(单链表每个节点多占 4 字节 / 8 字节,双向链表多占 8 字节 / 16 字节),空间密度低;
- 优点:容量动态增长,无需提前预留空间,元素数量 = 内存占用(除指针外)。无需连续内存,可利用离散的小内存块,内存利用率更高;