c语言双向链表包含头结点,C语言之双向链表(头结点与节点结构不相同)

双向链表主要注意:

1、插入节点要考虑到是在第1个节点和最后一个节点上,或者是中间,因情况不同处理的方法也不同

2、移除链表上的一个节点要考虑是1个节点还是最后一个节点上,或者是中间,因情况不同处理的方法也不同

头文件:

#ifndef __PLink2_H

#define __PLink2_H

typedef struct Node

{

char name[20];

char author[20];

float price;

int num;

struct Node *prev;

struct Node *Next;

}Node;

typedef struct Head

{

int len;

struct Node *Next;

}Head;

Head *CreateHead2(); //创建一个头结点

int DestroyHead2(Head *head); //删除整条链表

Node *CreateNode2(Node *node); //申请节点内存空间(malloc)

int DestroyNode2(Node *node); //删除节点的内存

int InsertNodeAtHead2(Head *head, Node *NewNode); //在链表中插入到第一个节点

int RemoveNode2(Head *head, Node *node); //从链表中移除一个节点,但不删除内存

Node *SreachNode2(Head *head, char *name); //搜索链表中的一个节点

int AddNode2(Head *head, Node *node); //向链表追加一个节点

int InsertNode(Head *head, Node *node, int add); //在链表指定位置上插入一个节点

int TwinLink();

int PrintfList2(Head *head);

#endif

源文件(.c):

#include "PLink2.h"

#include #include #include //创建头链表的内存空间

Head *CreateHead2()

{

Head *New = NULL;

New = (Head *)malloc(sizeof(Head) );

if(New == NULL)

{

printf("Error malloc failed\n");

return NULL;

}

memset(New, 0, sizeof(Head));

New->Next = NULL;

return New;

}

//删除整条链表的内存空间

int DestroyHead2(Head *head)

{

Node *next = NULL;

Node *node = NULL;

if(head == NULL)

{

return -1;

}

node = head->Next;

while(node != NULL)

{

next = node->Next;

DestroyNode2(node);

node = next;

}

free(head);

head = NULL;

return 0;

}

//创建申请节点内存空间(malloc)

Node *CreateNode2(Node *node)

{

Node *pstNew = NULL;

pstNew = (Node *)malloc(sizeof(Node) );

if(pstNew == NULL)

{

printf("Error malloc failed\n");

return NULL;

}

if(node != NULL)

{

memcpy(pstNew, node, sizeof(Node) );

pstNew->prev = NULL;

pstNew->Next = NULL;

}

else

{

memset(pstNew, 0, sizeof(Node));

}

return pstNew;

}

//删除节点内存空间

int DestroyNode2(Node *node)

{

if(node == NULL) return -1;

free(node);

node = NULL;

return 0;

}

//每次插入新节点都在第一个节点插入

int InsertNodeAtHead2(Head *head, Node *NewNode)

{

Node *temp = NULL;

if(head == NULL || NewNode ==NULL)

{

printf("InsertNodeAtHead is failed\n");

return -1;

}

temp = head->Next;

head->Next = NewNode;

NewNode->Next = temp;

NewNode->prev = NULL;

if(temp != NULL)

{

temp->prev = NewNode;

}

head->len++;

return 0;

}

//从链表中移除一个节点,但不删除内存

int RemoveNode2(Head *head, Node *node)

{

Node *temp = NULL;

if(head == NULL || node ==NULL) return -1;

temp = head->Next;

while(temp != NULL)

{

if(temp == node ) break;

temp = temp->Next;

}

if(temp == NULL) return -1; //空链表

if(temp->prev != NULL) //不是第一个节点

{

temp->prev->Next = temp->Next;

}

else //第一个节点

{

head->Next = temp->Next;

}

if(temp->Next != NULL) //不是最后节点

{

temp->Next->prev = temp->prev;

}

temp->prev = NULL;

temp->Next = NULL;

head->len--;

return 0;

}

//搜索链表中的一个节点

Node *SreachNode2(Head *head, char *name)

{

Node *node = NULL;

if(head == NULL || name ==NULL) return NULL;

node = head->Next;

while(node != NULL)

{

// if(node->name == name) //非字符串比较

if(strcmp(node->name, name) == 0 )

{

break;

}

node = node->Next;

}

return node;

}

//在双向链表末尾追加一个节点

int AddNode2(Head *head, Node *node)

{

Node *last = NULL;

Node *temp = NULL;

if(head == NULL || head == NULL) return -1;

temp = head->Next;

if(temp == NULL)

{

head->Next = node;

node->prev = NULL;

node->Next = NULL;

}

else

{

while(temp != NULL) //最后一个节点时,跳出循环

{

last = temp;

temp = temp->Next;

}

node->prev = last;

last->Next = node;

node->Next = NULL;

}

head->len++;

return 0;

}

//在链表指定位置上插入一个节点

int InsertNode(Head *head, Node *node, int add)

{

Node *temp = NULL;

if(head == NULL || head == NULL || add <= 0) return -1;

if(add == 1)

{

InsertNodeAtHead2(head, node);

}

else

{

temp = head->Next;

while(temp != NULL)

{

if(add == 1)

{

break;

}

add--;

temp = temp->Next;

}

if( (temp != NULL) && (add == 1) ) //插入到链表中某个节点上(2-链表最后一个)

{

node->Next = temp->prev->Next;

temp->prev->Next = node;

node->prev = temp->prev;

temp->prev = node;

}

else if( (temp == NULL) && (add == 1) ) //向链表追加一个节点

{

AddNode2(head, node);

}

else if( (temp == NULL) && (add > 1) ) //超出了插入节点的范围

{

return -1;

}

}

head->len++;

return 0;

}

测试代码:

//填写节点数据

int NodeData(Node *node, char *name, char *author, float price, int num)

{

if(node == NULL) return -1;

strcpy(node->name, name);

strcpy(node->author, author);

node->price = price;

node->num = num;

return 0;

}

//打印链表

int PrintfList2(Head *head)

{

Node *p = head->Next;

if(head == NULL) return -1;

while(p != NULL)

{

printf("%s\n", p->name);

p = p->Next;

}

printf("\n");

return 0;

}

//测试个函数功能

int TwinLink()

{

Head *head = (Head *)CreateHead2();

Node *Newnode = NULL;

Node node;

NodeData(&node, "aaa", "zhangsan", 100.05, 5); //填写链表的数据

Newnode = CreateNode2(&node); //创建一个节点并将填写的数据写入节点中

AddNode2(head, Newnode); //向链表追加一个节点

PrintfList2(head); //打印链表的数据

NodeData(&node, "bbb", "lisi", 55.44, 56);

Newnode = CreateNode2(&node);

InsertNodeAtHead2(head, Newnode); //插入一个节点到链表的第1个节点的位置上

PrintfList2(head);

NodeData(&node, "ccc", "wangwu", 22.05, 9);

Newnode = CreateNode2(&node);

InsertNode(head, Newnode, 2); //向链表插入一个节点到第2个节点的位置上

PrintfList2(head);

Newnode = SreachNode2(head, "ccc"); //在链表上搜索一个节点

RemoveNode2(head, Newnode); //在链表上移除一个节点

DestroyNode2(Newnode); //删除这个节点的内存

PrintfList2(head);

return 0;

}

测试效果图:

3a4010b554c2e2854d8884fb7062b7f1.png

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值