封装链表:
尾添加的效率低、非法下标的判断效率也非常低
1,单链表
节点:数据域+指针域
单链表的数据项:
头节带
尾节点
节点数量
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
//封装了带头节点的单链表
typedef struct Node
{
TYPE date;
struct Node* next;
}Node;
Node* create_node(TYPE val)
{
Node* node = malloc(sizeof(Node));
node->date = val;
node->next = NULL;
return node;
}
//封装单链表结构
typedef struct List
{
Node* head;//头指针
Node* tail;//尾指针
size_t size;//节点数量
}List;
//创建单链表
List* create_list(void)
{
List* list = malloc(sizeof(List));
list->head = create_node(0);//带头节点的链表
list->tail = NULL;
list->size = 0;
}
//头添加
void add_head_list(List* list,TYPE val)
{
Node* node = create_node(val);
if(0 == list->size)
{
list->head->next = node;
list->tail = node;
}
else
{
node->next = list->head->next;
list->head->next = node;
}
list->size++;
}
//尾添加
void add_tail_list(List* list,TYPE val)
{
Node* node = create_node(val);
if(0 == list->size)
{
list->head->next = node;
list->tail = node;
}
else
{
list->tail->next = node;
list->tail = node;
}
list->size++;
}
//头删除
bool del_head_list(List* list)
{
if(0 == list->size) return false;
Node* temp = list->head->next;
list->head->next = temp->next;
if(1 == list->size) list->tail = NULL;
list->size--;
free(temp);
return true;
}
//尾删除
bool del_tail_list(List* list)
{
if(0 == list->size) return false;
free(list->tail);
if(1 == list->size)
{
list->head->next = NULL;
list->tail = NULL;
}
else
{
Node* prev = list->head->next;
while(prev->next != list->tail) prev=prev->next;
prev->next = NULL;
list->tail = prev;
}
list->size--;
}
//插入
bool insert_list(List* list,size_t index,TYPE val)
{
if(0 >= index || index >= list->size) return false;
Node* node = create_node(val);
Node* prev = list->head->next;
for(int i=1;i<index;i++) prev=prev->next;
node->next = prev->next;
prev->next = node;
list->size++;
return true;
}
//按值删除
bool del_val_list(List* list,TYPE val)
{
if(val == list->head->next->date) return del_head_list(list);
if(val == list->tail->date) return del_tail_list(list);
for(Node* n=list->head->next;n->next;n=n->next)
{
if(val == n->next->date)
{
Node* temp = n->next;
n->next = temp->next;
free(temp);
list->size--;
return true;
}
}
return false;
}
//按位置删除
bool del_index_list(List* list,size_t index)
{
if(index >= list->size) return false;
if(0 == index) return del_head_list(list);
if(list->size-1 == index) return del_tail_list(list);
Node* prev = list->head->next;
for(int i=1;i<index;i++)
{
prev = prev->next;
}
Node* temp = prev->next;
prev->next = temp->next;
free(temp);
list->size--;
return true;
}
//按位置修改
bool modify_index_list(List* list,size_t index,TYPE val)
{
if(index >= list->size) return false;
Node* prev = list->head->next;
for(int i=0;i<index;i++) prev = prev->next;
prev->date = val;
return true;
}
//按值修改
size_t modify_val_list(List* list,TYPE old,TYPE val)
{
size_t cnt=0;
for(Node* n=list->head->next;n;n=n->next)
{
if(n->date == old)
{
n->date = val;
cnt++;
}
}
return cnt;
}
//查询
int query_list(List* list,TYPE val)
{
int i = 0;
for(Node* n=list->head;n->next;n=n->next)
{
if(val == n->next->date) return i;
i++;
}
return -1;
}
//访问
bool access_list(List*list,size_t index,TYPE* val)
{
if(index >= list->size) return false;
Node* n = list->head->next;
for(int i=0;i<index;i++)
{
n=n->next;
}
*val = n->date;
return true;
}
//排序
void sort_list(List* list)
{
for(Node* i=list->head->next;i->next;i=i->next)
{
for(Node* j=i->next;j;j=j->next)
{
if(i->next > j->next)
{
TYPE temp = i->date;
i->date = j->date;
j->date = temp;
}
}
}
}
//清空
void clear_list(List* list)
{
//while(list->size) del_tail_list(list);耦合依赖高
while(list->head->next)
{
Node* temp = list->head->next;
list->head->next = temp->next;
free(temp);
}
list->tail = NULL;
list->size = 0;
}
//销毁
void destory_list(List* list)
{
clear_list(list);
free(list->head);
free(list);
}
//遍历
void show_list(List* list)
{
for(Node* n=list->head->next;n;n=n->next)
{
printf("%d ",n->date);
}
printf("\n");
}
int main(int argc,const char* argv[])
{
List* list = create_list();
for(int i=0;i<10;i++)
{
add_head_list(list,i);
}
show_list(list);
del_head_list(list);
show_list(list);
del_tail_list(list);
show_list(list);
insert_list(list,1,99);
show_list(list);
del_val_list(list,99);
show_list(list);
del_index_list(list,1);
show_list(list);
modify_index_list(list,2,99);
modify_index_list(list,3,99);
show_list(list);
modify_val_list(list,99,88);
show_list(list);
printf("%d",query_list(list,88));
}
静态链表:
节点:
数据域
游标
静态链表的节点存储在连续的内存中,通过游标来访问下一个节点
这种链表在插入删除时只需要修改游标的的值,而不用申请、释放节点内存就可以达到类似链式结构的效果
牺牲了随机访问的功能,也没法达到链表动态申请内存的效果,只是给没有指针的编程语言实现链表的一种方式,实用性不大
循环链表
链表的最后一个节点的next不在指向NULL,而是指向头结点,这种链表称为单向循环链表,简称循环链表
它的好处是可以通过任意一个节点遍历整个链表
双向循环链表
节点
前驱指针 prev
数据域
后继指针 next
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
//演示双向循环列表
typedef struct Node
{
struct Node* prev;//前驱
TYPE date;
struct Node* next;//后继
}Node;
//创建
Node* create_node(TYPE date)
{
Node* node=malloc(sizeof(Node));
node->date = date;
node->prev = node;
node->next = node;
}
//带头结点
//依赖函数
void _add_list(Node* p,Node* n,TYPE date)
{
Node* node = create_node(date);
node->prev = p;
node->next = n;
p->next = node;
n->prev = node;
}
//头添加
void add_head_list(Node* head,TYPE date)
{
_add_list(head,head->next,date);
}
//尾添加
void add_tail_list(Node* head,TYPE date)
{
_add_list(head->prev,head,date);
}
//插入
bool insert_list(Node* head,size_t index,TYPE date)
{
Node* n = head->next;
for(int i=0;i<index;i++)
{
n = n->next;
if(head == n) return false;
}
_add_list(n->prev,n,date);
return true;
}
//删除依赖函数
void _del_list(Node* node)
{
Node* p = node->prev;
Node* n = node->next;
p->next = n;
n->prev = p;
free(node);
}
//值删除
bool del_val_list(Node* head,TYPE date)
{
for(Node* n = head->next;head != n;n=n->next)
{
if(date == n->date)
{
_del_list(n);
return true;
}
}
return false;
}
//址删除
bool del_index_list(Node* head,size_t index)
{
Node* n = head->next;
for(int i=0;i<index;i++)
{
n=n->next;
if(head == n) return false;
}
_del_list(n);
return true;
}
//遍历
void show_list(Node* head)
{
for(Node* n=head->next;head != n;n=n->next)
{
printf("%d ",n->date);
}
printf("\n");
}
int main(int argc,const char* argv[])
{
Node* head = create_node(0);
for(int i=0;i<10;i++)
{
add_head_list(head,i);
}
show_list(head);
add_tail_list(head,99);
show_list(head);
insert_list(head,10,66);
show_list(head);
del_index_list(head,88);
show_list(head);
del_val_list(head,66);
show_list(head);
}