代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
* 使用头节点
*/
typedef struct node {
int data;
struct node *prev;
struct node *next;
}NODE, *PNODE;
// 初始化
void init(PNODE *);
// 是否为空
bool is_empty(PNODE);
// 遍历
void traverse(PNODE);
// 头插法追加节点
bool head_add(PNODE *, int);
// 尾插法追加节点
bool rear_add(PNODE *, int);
// 求长度(不算头节点)
int len(PNODE);
// 插入节点(选择不使用PNODE *类型形参)
bool insert(PNODE, int, int);
// 删除节点(选择不使用PNODE *类型形参)
bool delete(PNODE, int, int *);
// 清空链表(不释放头节点, 同样选择不使用PNODE *类型形参)
void clear(PNODE);
// 函数中的删除操作未使用delete函数
void clear(PNODE head)
{
PNODE q;
printf("clear...\n");
if (is_empty(head))
return;
while (head->next) {
q = head->next;
head->next = q->next;
free(q);
}
}
bool delete(PNODE head, int pos, int *pVal)
{
PNODE p;
int i = 0;
printf("delete 位置%d", pos);
if (NULL == head) {
printf(" 失败,链表未初始化!\n");
return false;
}
if (pos < 1 || pos > len(head)) {
printf(" 失败,错误的位置\n");
return false;
}
p = head;
while (i < pos) {
p = p->next;
++i;
}
*pVal = p->data;
p->prev->next = p->next;
// 如果不是尾节点
if (p->next) {
p->next->prev = p->prev;
}
printf("成功 值为 %d\n", *pVal);
return true;
}
bool insert(PNODE head, int pos, int val)
{
PNODE tmp, p;
int i = 0;
printf("insert 位置%d 值%d", pos, val);
if (NULL == head) {
printf(" 失败,请先初始化!\n");
return false;
}
if (pos < 1 || pos > len(head)+1) {
printf(" 失败,错误的位置\n");
return false;
}
p = head;
while (i < pos - 1) {
p = p->next;
++i;
}
tmp = (PNODE)malloc(sizeof(NODE));
tmp->data = val;
tmp->prev = p;
tmp->next = p->next;
p->next = tmp;
printf(" 成功\n");
return true;
}
int len(PNODE head)
{
int i = 0;
if (is_empty(head))
return 0;
while (head->next) {
head = head->next;
++i;
}
return i;
}
bool rear_add(PNODE *pHead, int val)
{
printf("rear_add %d", val);
PNODE tmp, rear;
if (*pHead == NULL) {
printf(" 插入失败请先初始化!\n");
return false;
}
// 找尾节点
rear = *pHead;
while (rear->next) {
rear = rear->next;
}
tmp = (PNODE)malloc(sizeof(NODE));
tmp->data = val;
tmp->prev = rear;
tmp->next = NULL;
rear->next = tmp;
printf(" 插入成功\n");
return true;
}
bool head_add(PNODE *pHead, int val)
{
printf("head_add %d", val);
PNODE tmp;
if (*pHead == NULL) {
printf(" 插入失败请先初始化!\n");
return false;
}
tmp = (PNODE)malloc(sizeof(NODE));
tmp->data = val;
tmp->prev = *pHead;
tmp->next = (*pHead)->next;
(*pHead)->next = tmp;
printf(" 插入成功\n");
return true;
}
void traverse(PNODE head)
{
if (is_empty(head)) {
printf("链表为空!\n");
return;
}
PNODE p;
p = head->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}
putchar('\n');
}
// 未初始化或头节点next指向NULL时,都返回true
bool is_empty(PNODE head)
{
if (! head || ! head->next)
return true;
return false;
}
void init(PNODE *pHead)
{
int val;
PNODE head, tmp, rear;
head = (PNODE)malloc(sizeof(NODE));
if (! head) {
printf("malloc error\n");
return;
}
// head node not asign data
head->prev = NULL;
head->next = NULL;
rear = head;
printf("请输入双向链表节点数据(0为终止输入):\n");
while (1) {
scanf("%d", &val);
if (val == 0)
break;
tmp = (PNODE)malloc(sizeof(NODE));
if (! tmp) {
printf("malloc error\n");
return;
}
tmp->data = val;
tmp->prev = rear;
tmp->next = NULL;
rear->next = tmp;
rear = tmp;
}
*pHead = head;
}
int main(void)
{
PNODE head = NULL;
int val;
head_add(&head, 14);
init(&head);
traverse(head);
head_add(&head, 13);
head_add(&head, 12);
head_add(&head, 11);
traverse(head);
rear_add(&head, 31);
rear_add(&head, 32);
rear_add(&head, 33);
traverse(head);
printf("长度为:%d\n", len(head));
insert(head, 0, 100);
insert(head, 50, 100);
insert(head, 1, 10);
insert(head, 1, 9);
traverse(head);
delete(head, 0, &val);
delete(head, 50, &val);
printf("长度为:%d\n", len(head));
delete(head, 1, &val);
traverse(head);
delete(head, 3, &val);
traverse(head);
delete(head, 7, &val);
traverse(head);
clear(head);
traverse(head);
return 0;
}
output
[root@8be225462e66 c]# gcc doubly_linklist.c && ./a.out
head_add 14 插入失败请先初始化!
请输入双向链表节点数据(0为终止输入):
21
22
23
0
21 22 23
head_add 13 插入成功
head_add 12 插入成功
head_add 11 插入成功
11 12 13 21 22 23
rear_add 31 插入成功
rear_add 32 插入成功
rear_add 33 插入成功
11 12 13 21 22 23 31 32 33
长度为:9
insert 位置0 值100 失败,错误的位置
insert 位置50 值100 失败,错误的位置
insert 位置1 值10 成功
insert 位置1 值9 成功
9 10 11 12 13 21 22 23 31 32 33
delete 位置0 失败,错误的位置
delete 位置50 失败,错误的位置
长度为:11
delete 位置1成功 值为 9
10 11 12 13 21 22 23 31 32 33
delete 位置3成功 值为 12
13 21 22 23 31 32 33
delete 位置7成功 值为 33
13 21 22 23 31 32
clear...
链表为空!
[root@8be225462e66 c]#