#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//双向链表一般也是无头式数组链表,且采用再封装
typedef struct NODE{ //创建节点的结构的模板
int data;
struct NODE *front;
struct NODE *tail;
}NODE ,*LPNODE;
LPNODE createNode(int data) //创建新节点的模板
{
LPNODE newNode = (LPNODE)malloc(sizeof(NODE));
newNode->front = NULL;
newNode->tail = NULL;
assert(newNode);
newNode->data = data;
return newNode;
}
typedef struct DList //创建链表的模板的结构
{
LPNODE frontNode;
LPNODE tailNode;
int curSize;
}DLIST ,*LPDLIST;
LPDLIST createDList() //创建链表的模板
{
LPDLIST list = (LPDLIST)malloc(sizeof(DLIST));
assert(list);
list->frontNode = NULL;
list->tailNode = NULL;
list->curSize = 0;
return list;
}
void push_front(LPDLIST list,int data) //头插法
{
LPNODE newNode = createNode(data);
if (NULL == list)
{
return;
}
if (list->curSize == 0)
{
list->frontNode = newNode;
list->tailNode = newNode;
list->curSize++;
}
else
{
newNode->tail = list->frontNode;
list->frontNode ->front=newNode;
list->frontNode = newNode;
list->curSize++;
}
}
void push_back(LPDLIST list, int data)
{
LPNODE newNode = createNode(data);
if (NULL == list)
{
return;
}
if (list->curSize == 0)
{
list->frontNode = newNode;
list->tailNode = newNode;
list->curSize++;
}
else
{
list->tailNode->tail = newNode;
newNode->front=list->tailNode;
list->tailNode = newNode;
list->curSize++;
}
}
void printfByFront(LPDLIST list) //前向指针打印,从右往左
{
LPNODE pmove = list->tailNode;
while (pmove!=NULL)
{
printf("%d\t",pmove->data);
pmove = pmove->front;//自己赋值为自己的上一个节点
}
printf("\n");
}
void printfByTail(LPDLIST list) //后向指针打印,从左往右
{
LPNODE pmove = list->frontNode;
while (pmove)
{
printf("%d\t", pmove->data);
pmove = pmove->tail;//自己赋值为自己的下一个节点,等于单链表的x=x->next
}
printf("\n");
}
void push_Data(LPDLIST list, int appoinData, int data)
{
if (NULL == list || list->curSize == 0)
{
printf("链表属性为空或内存大小为0;无法插入");
}
else if (list->frontNode->data == appoinData)
{
push_front(list, data);
}
else if (list->tailNode->data == appoinData)
{
push_back(list, data);
}
else
{
LPNODE proNode = list->frontNode;
LPNODE curNode = list->frontNode;
while (curNode != NULL&&curNode->data != appoinData)
{
proNode = curNode;
curNode = curNode->tail;
}
if (curNode == NULL)
{
printf("链表已空,未找到指定插入数据,无法插入\n");
return;
}
else
{
LPNODE newNode = createNode(data);
curNode->front = newNode;
newNode->tail = curNode;
newNode->front = proNode;
proNode->tail = newNode;
list->curSize++;
}
}
}
void push_Loca(LPDLIST list, int Location, int data)
{
if (NULL == list || list->curSize == 0)
{
printf("链表属性为空或内存大小为0;无法插入\n");
}
LPNODE proNode = list->frontNode;
LPNODE curNode = list->frontNode;
while (NULL != curNode->tail&&list->curSize != 0)
{
proNode = curNode;
curNode = curNode->tail;
}
if (Location == list->curSize)
{
push_back(list, data);
return;
}
else if (Location == 1)
{
push_front(list, data);
return;
}
else
{
LPNODE newNode = createNode(data);
curNode->front = newNode;
newNode->front = proNode;
proNode->tail = newNode;
newNode->tail = curNode;
list->curSize++;
}
}
void revise_Loca(LPDLIST list, int Location, int data)
{
if (NULL == list || list->curSize == 0)
{
printf("链表不存在,或内存为0,无法修改数据\n");
}
LPNODE proNode = list->frontNode;
LPNODE curNode = list->frontNode;
int a=1;
while (NULL != curNode->tail&&Location!=a)
{
proNode = curNode;
curNode = curNode->tail;
a++;
}
if (curNode->tail== NULL)
{
printf("到达尾部,未查找到修改位置,无法修改\n");
}
else
{
curNode->data = data;
}
}
void recise_Data(LPDLIST list, int appoinData, int data)
{
if (NULL == list || list->curSize == 0)
{
printf("链表没有足够空间,无法删除\n");
}
LPNODE proNode = list->frontNode;
LPNODE curNode = list->frontNode;
while (curNode->tail != NULL&&appoinData != curNode->data)
{
proNode = curNode;
curNode = curNode->tail;
}
if (curNode->tail == NULL)
{
printf("链表已空,未找到指定数据,无法修改\n");
}
else
{
curNode->data = data;
}
}
void delect_head(LPDLIST list)
{
if (list == NULL || list->curSize == 0)
{
return;
}
LPNODE nextNode = list->frontNode->tail;
free(list->frontNode);
list->frontNode = nextNode;
if (nextNode != NULL)//如果链表被删除还有至少一个list->front节点
{
nextNode->front = NULL;
}
else /*if (list->curSize == 1)*/ //只有当前一个节点,没有next节点时
{
list->tailNode = NULL;
return;
}
list->curSize--;
}
void delect_feather(LPDLIST list)
{
if (list == NULL || list->curSize == 0)
{
return;
}
LPNODE proNode = list->tailNode->front;
free(list->tailNode);
list->tailNode = proNode;
if (proNode != NULL)
{
proNode->tail = NULL;
}
else
{
list->frontNode = NULL;
}
list->curSize--;
//if (proNode != NULL) //如果链表被删除还有至少一个节点将原本节点指向最后一个节点的指针置空,不然指向数组最后已经置空的地方,里面是杂数据
//{
// proNode->tail = NULL;
//}
//else
//{
// list->frontNode = NULL;
// return;
//}
}
void deldect_appoinData(LPDLIST list, int appoinData)
{
if (list == NULL || list->curSize == 0)
{
printf("链表为空无法删除\n");
return;
}
if (list->frontNode->data == appoinData)
{
delect_head(list);
return;
}
if (list->tailNode->data == appoinData)
{
delect_feather(list);
return;
}
LPNODE proNode = list->frontNode;
LPNODE curNode = list->frontNode;
while (curNode != NULL&&curNode->data != appoinData)
{
proNode = curNode;
curNode = curNode->tail;
}
if (curNode == NULL)
{
printf("未找到指定的数据,无法删除\n");
return;
}
else if (curNode->tail==NULL)//表尾时tail为空,使用尾删
{
delect_feather(list);
return;
}
else
{
proNode->tail = curNode->tail;
curNode->tail->front = proNode;
free(curNode);
curNode = NULL;
list->curSize--;
}
}
int main()
{
LPDLIST list = createDList(); //调用创建链表模板的函数创建初始化链表
push_front(list, 1);
push_front(list, 2);
printfByFront(list);
printfByTail(list);
push_back(list, 3);
printfByFront(list);
printfByTail(list);
push_Data(list, 2, 4);
printfByFront(list);
printfByTail(list);
push_Loca(list, 2, 5);
printfByFront(list);
printfByTail(list);
revise_Loca(list, 2, 666);
printfByFront(list);
printfByTail(list);
recise_Data(list, 666, 2);
printfByFront(list);
printfByTail(list);
delect_head(list);
printfByFront(list);
printfByTail(list);
delect_feather(list);
printfByFront(list);
printfByTail(list);
deldect_appoinData(list,1);
printfByFront(list);
printfByTail(list);
}
C语言双向链表
最新推荐文章于 2024-07-23 19:36:52 发布