前言单向链表
单链表节点中只有一个指向其后继的指针,这使得单链表只能从头节点依次顺序地向后遍历。若要访问某个节点得前驱节点(插入、删除操作时),只能从头开始遍历
- 为了克服单向链表的缺点,引入了双向链表,双向链表节点中有两个next和prev,分别指向下一个节点地址和上一个节点地址
如图理解:
按位置前插入元素:
删除元素:
线性表链式存储结构,双向链表的实现
定义声明函数:
/**
*C实现:定义声明函数
*/
#ifndef CHAIN_H_INCLUDED
#define CHAIN_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
//双向链表
typedef struct ListNode_s{ //节点结构
int data; //数据
struct ListNode_s* next;//指向下一个节点地址
struct ListNode_s* prev;//指向上一个节点地址
}LIST_NODE_S;
typedef struct List_s{ //链表结构
LIST_NODE_S* head; //头节点指针
LIST_NODE_S* tail; //尾节点指针
LIST_NODE_S* frwd; //应用于迭代
}LIST_S;
//初始化链表
void list_s_init(LIST_S* list);
//释放化链表
void list_s_deinit(LIST_S* list);
//判断链表空
int list_s_empty(LIST_S* list);
//追加元素
void list_s_append(LIST_S* list, int data);
//插入元素(位置按前插)
int list_s_insert(LIST_S* list, size_t pos, int data);
//删除元素(按位置删除)
int list_s_erase(LIST_S* list, size_t pos);
//删除元素(相同元素全删除)
void list_s_remove(LIST_S* list, int data);
//全删元素
void list_s_clear(LIST_S* list);
//查看元素(按位置取值)
int* list_s_at(LIST_S* list, size_t pos);
//元素数量
size_t list_s_size(LIST_S* list);
//正向迭代
void list_s_begin(LIST_S* list);
//向前迭
int* list_s_next(LIST_S* list);
//反向迭代
void list_s_reverse(LIST_S* list);
//向后迭
int* list_s_prev(LIST_S* list);
//当前迭代(当前值)
int* list_s_current(LIST_S* list);
//判断迭代结束
int list_s_end(LIST_S* list);
#endif //CHAIN_H_INCLUDED
声明函数实现:
/**
*C实现:声明函数实现
*/
#include "chain.h"
//创建节点
static LIST_NODE_S* create_lists_node(int data, LIST_NODE_S* next, LIST_NODE_S* prev){
LIST_NODE_S* node = malloc(sizeof(LIST_NODE_S));
node->data = data;
node->next = next;
node->prev = prev;
return node;
}
//销毁节点
static LIST_NODE_S* destroy_lists_node(LIST_NODE_S* node, LIST_NODE_S** prev){
LIST_NODE_S* next = node->next;
if(prev) *prev = node->prev;
free(node);
return next;
}
//初始化链表
void list_s_init(LIST_S* list){
list->head = NULL;
list->tail = NULL;
list->frwd = NULL;
}
//释放化链表
void list_s_deinit(LIST_S* list){
while(list->head){
list->head = destroy_lists_node(list->head, NULL);
}
list->tail = NULL;
list->frwd = NULL;
}
//判断链表空
int list_s_empty(LIST_S* list){
return !list->head && !list->tail;
}
//追加元素
void list_s_append(LIST_S* list, int data){
list->tail = create_lists_node(data, NULL, list->tail);
if(list->tail->prev){
list->tail->prev->next = list->tail;
}else{
list->head = list->tail;
}
}
//插入元素(位置按前插)
int list_s_insert(LIST_S* list, size_t pos, int data){
LIST_NODE_S* find = list->head;
for(; find; find = find->next){
if(!pos--){
LIST_NODE_S* node = create_lists_node(data, find, find->prev);
if(node->prev){
node->prev->next = node;
}else list->head = node;
node->next->prev = node;
return 1;
}
}
return 0;
}
//删除元素(按位置删除)
int list_s_erase(LIST_S* list, size_t pos){
LIST_NODE_S* find = list->head;
for(; find; find = find->next){
if(!pos--){
LIST_NODE_S* prev = NULL;
LIST_NODE_S* next = destroy_lists_node(find, &prev);
if(prev){
prev->next = next;
}else list->head = next;
if(next){
next->prev = prev;
}else list->tail = prev;
return 1;
}
}
return 0;
}
//删除元素(相同元素全删除)
void list_s_remove(LIST_S* list, int data){
LIST_NODE_S* find = list->head;
LIST_NODE_S* next = NULL;
for(; find; find = next){
next = find->next;
if(find->data == data){
LIST_NODE_S* prev = NULL;
LIST_NODE_S* next = destroy_lists_node(find, &prev);
if(prev){
prev->next = next;
}else list->head = next;
if(next){
next->prev = prev;
}else list->tail = prev;
}
}
}
//全删元素
void list_s_clear(LIST_S* list){
list_s_deinit(list);
}
//查看元素(按位置取值)
int* list_s_at(LIST_S* list, size_t pos){
LIST_NODE_S* find = list->head;
for(; find; find = find->next){
if(!pos--) return &find->data;
}
return NULL;
}
//元素数量
size_t list_s_size(LIST_S* list){
size_t size = 0;
LIST_NODE_S* find = list->head;
for(; find; find = find->next)size++;
return size;
}
//正向迭代
void list_s_begin(LIST_S* list){
list->frwd = list->head;
}
//向前迭
int* list_s_next(LIST_S* list){
int* data = &list->frwd->data;
list->frwd = list->frwd->next;
return data;
}
//反向迭代
void list_s_reverse(LIST_S* list){
list->frwd = list->tail;
}
//向后迭
int* list_s_prev(LIST_S* list){
int* data = &list->frwd->data;
list->frwd = list->frwd->prev;
return data;
}
//当前迭代(当前值)
int* list_s_current(LIST_S* list){
return &list->frwd->data;
}
//判断迭代结束
int list_s_end(LIST_S* list){
return !list->frwd;
}
实现函数验证:
/**
*C实现:实现函数验证
*/
#include "chain.h"
int main()
{
int i;
LIST_S lists;
list_s_init(&lists);//初始
for(i = 0; i < 10; i++){
list_s_append(&lists, (i+1)*10);//追加
}
list_s_insert(&lists, 2, 25);//前插(2的位置是30前插)
list_s_erase(&lists, 3);//位置删除(3的位置还是30将删)
//追加(为了测相同数据删除)
list_s_append(&lists, 25);
//相同数据删除(2的位置25删除)与(后面追加的25删除)
list_s_remove(&lists, 25);
//位置取数据,(2的位置当前是40)
printf("取2位置=%d\n", *list_s_at(&lists, 2));
//正向遍历
list_s_begin(&lists);
//返回frwd(返回当前是否是头数据)
printf("frwd头数据=%d\n", *list_s_current(&lists));
while(!list_s_end(&lists)){//判断结束frwd迭代
printf("%d\n", *list_s_next(&lists));//向前迭代观察数据
}
printf("数量=%d\n", list_s_size(&lists));//元素数量
//全销毁数据(就是调用list_s_deinit)
list_s_clear(&lists);
printf("数据为空%d\n", !list_s_empty(&lists));//为空0
printf("数量=%d\n", list_s_size(&lists));//元素数量
list_s_deinit(&lists);//释放
return 0;
}