// dlink_list.h -- header of double link list
#ifndef __DLINK_LIST_H__
#define __DLINK_LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int datatype;
typedef struct node{
datatype val;
struct node* prev;
struct node* next;
}node_t, * pnode_t;
// create node
pnode_t create_node(datatype);
// init double link list
pnode_t dlink_init();
// check if empty
bool dlink_is_empty(pnode_t);
// insert to header
void dlink_head_insert(pnode_t, datatype);
// insert to tail
void dlink_tail_insert(pnode_t, datatype);
// insert by index
void dlink_index_insert(pnode_t, datatype, int);
// remove from head
void dlink_head_remove(pnode_t, datatype*);
// remove from tail
void dlink_tail_remove(pnode_t, datatype*);
// remove by index
void dlink_index_remove(pnode_t, datatype*, int);
// show double link list
void dlink_show(pnode_t);
// clear double link list
void dlink_clear(pnode_t);
// destroy double link list
void dlink_destroy(pnode_t*);
#endif
#include "dlink_list.h"
// create node
pnode_t create_node(datatype d){
pnode_t node = (pnode_t)malloc(sizeof(node_t));
if(!node){
perror("create_node> create node fail> ");
return NULL;
}
else{
node->val = d;
node->prev = NULL;
node->next = NULL;
return node;
}
}
// init double link list
pnode_t dlink_init(){
pnode_t head = create_node(0);// set val to 0 which counts node
if(!head){
perror("dlink_init> create head fail> ");
return NULL;
}
else
return head;
}
// check if empty
bool dlink_is_empty(pnode_t p){
if(!p){
printf("dlink_is_empty> double link list had not inited\n");
return false;
}
else
return (p->val == 0);
}
// insert to header
void dlink_head_insert(pnode_t p, datatype d){
if(!p){
printf("dlink_head_insert> double link list had not inited\n");
return;
}
else{
pnode_t node = create_node(d);
node->next = p->next;
if(p->next)
p->next->prev = node;
node->prev = p;
p->next = node;
p->val++;
return;
}
}
// insert to tail
void dlink_tail_insert(pnode_t p, datatype d){
if(!p){
printf("dlink_tail_insert> double link list had not inited\n");
return;
}
else{
pnode_t node = create_node(d);
pnode_t temp = p;
while(temp->next)
temp = temp->next;
node->next = temp->next;
node->prev = temp;
temp->next = node;
p->val++;
return;
}
}
// insert by index
void dlink_index_insert(pnode_t p, datatype d, int n){
if(!p){
printf("dlink_index_insert> double link list had not inited\n");
return;
}
if(n <= 1){
dlink_head_insert(p, d);
return;
}
else if(n > p->val){
dlink_tail_insert(p, d);
return;
}
else{
pnode_t node = create_node(d);
pnode_t temp = p;
int index = n - 1;
while(index--)
temp = temp->next;
node->next = temp->next;
temp->next->prev = node;
node->prev = temp;
temp->next = node;
p->val++;
return;
}
}
// remove from head
void dlink_head_remove(pnode_t p, datatype* pd){
if(!p){
printf("dlink_head_remove> double link list had not inited\n");
return;
}
else if(dlink_is_empty(p)){
printf("dlink_head_remove> double link list is empty\n");
return;
}
else{
pnode_t temp = p->next;
p->next = temp->next;
if(temp->next)
temp->next->prev = p;
*pd = temp->val;
free(temp);
p->val--;
}
}
// remove from tail
void dlink_tail_remove(pnode_t p, datatype* pd){
if(!p){
printf("dlink_tail_remove> double link list had not inited\n");
return;
}
else if(dlink_is_empty(p)){
printf("dlink_tail_remove> double link list is empty\n");
return;
}
else{
pnode_t i = p, j;
while(i->next->next)
i = i->next;
j = i->next;
i->next = j->next;
*pd = j->val;
free(j);
p->val--;
}
}
// remove by index
void dlink_index_remove(pnode_t p, datatype* pd, int n){
if(!p){
printf("dlink_index_remove> double link list had not inited\n");
return;
}
else if(dlink_is_empty(p)){
printf("dlink_index_remove> double link list is empty\n");
return;
}
else if(n <= 1){
dlink_head_remove(p, pd);
return;
}
else if(n >= p->val){
dlink_tail_remove(p, pd);
return;
}
else{
pnode_t i = p, j;
int index = n - 1;
while(index--)
i = i->next;
j = i->next;
i->next = j->next;
j->next->prev = i;
*pd = j->val;
free(j);
p->val--;
return;
}
}
// show double link list
void dlink_show(pnode_t p){
if(!p){
printf("dlink_show> double link list had not inited\n");
return;
}
else if(dlink_is_empty(p)){
printf("dlink_show> double link list is empty\n");
return;
}
else{
pnode_t temp = p->next;
while(temp){
printf("%-4d", temp->val);
temp = temp->next;
}
putchar(10);
return;
}
}
// clear double link list
void dlink_clear(pnode_t p){
if(!p){
printf("dlink_clear> double link list had not inited\n");
return;
}
else{
pnode_t i = p->next, j;
while(i){
j = i->next;
free(i);
i = j;
}
p->val = 0;
p->next = NULL;
return;
}
}
// destroy double link list
void dlink_destroy(pnode_t* pp){
if(!pp){
printf("dlink_destroy> double link list pointer had not inited\n");
return;
}
else if(!*pp){
printf("dlink_destroy> double link list had not inited\n");
return;
}
else{
dlink_clear(*pp);
free(*pp);
*pp = NULL;
return;
}
}
#include "dlink_list.h"
#include <time.h>
int main(){
pnode_t h = dlink_init();
srand(time(0));
for(size_t i = 0; i < 10; i++)
dlink_head_insert(h, rand()%100);
for(size_t i = 0; i < 10; i++)
dlink_tail_insert(h, rand()%100);
dlink_show(h);
datatype ret;
dlink_index_insert(h, 666, 2);
dlink_show(h);
dlink_index_remove(h, &ret, 5);
printf("ret:%d\n", ret);
dlink_show(h);
dlink_clear(h);
dlink_show(h);
dlink_destroy(&h);
}
26 6 76 84 60 40 56 95 34 62 31 21 17 64 1 66 40 35 77 96
26 666 6 76 84 60 40 56 95 34 62 31 21 17 64 1 66 40 35 77 96
ret:84
26 666 6 76 60 40 56 95 34 62 31 21 17 64 1 66 40 35 77 96
dlink_show> double link list is empty
链表和顺序表的区别:
相同点:逻辑结构都是线性结构
不同点:
顺序表的物理结构是顺序存储,支持随机访问,但是增删元素需要移动其他元素,增删效率低,且空间利用率不高,适合经常访问且体量不大的数据。
链表的物理结构是链式存储,不支持随机访问,需要根据指针逐个访问,但是增删元素不需要移动其他元素,增删效率高,且空间利用率高,适合较少访问但体量巨大的数据。