4.17 双向链表ADT实现

// 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

链表和顺序表的区别:

相同点:逻辑结构都是线性结构

不同点:

顺序表的物理结构是顺序存储,支持随机访问,但是增删元素需要移动其他元素,增删效率低,且空间利用率不高,适合经常访问且体量不大的数据。

链表的物理结构是链式存储,不支持随机访问,需要根据指针逐个访问,但是增删元素不需要移动其他元素,增删效率高,且空间利用率高,适合较少访问但体量巨大的数据。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值