双向链表基本操作以及优化可能

面试时面试官要求手写双向链表的 删除操作,当时没有考虑到边界条件,导致被刷;
现在 列举下代码以及优化,作为事后反思:

C 版本:

双向链表的结构定义

typedefstruct doubleLink
{
int data;
struct doubleLink *prior;
struct doubleLink *suffix;
}DOUBLE_LINK;

  

创建一个双向链表

/*创建一个双链表*/
DOUBLE_LINK *createDoubleLink()
{
DOUBLE_LINK *head = NULL;
head =(DOUBLE_LINK*)malloc(sizeof*head);
head->prior = NULL;
head->suffix = NULL;
return head;
}

  

插入函数

/*插入节点*/
bool insertNode(DOUBLE_LINK*head,int data)
{
if(head == NULL)
returnfalse;
DOUBLE_LINK *currNodep = NULL;
DOUBLE_LINK *nextp = NULL;
DOUBLE_LINK *newNodep = NULL;
for(currNodep = head;(nextp = currNodep->suffix)!= NULL; currNodep = nextp)
{
if(nextp->data == data)
returnfalse;
if(nextp->data > data)
break;
}
newNodep =(DOUBLE_LINK*)malloc(sizeof*newNodep);
if(newNodep == NULL)
returnfalse;
newNodep->data = data;
#if 1
/*需要插入双向链表时,遍历到需要插入的位置,开始对待插入的节点,前驱指针和后驱指针赋值,
后驱指针固定指向下一个节点指针,前驱需要区分 前指针是否是 头节点。
再对 当前节点的前驱指针赋值,需要区分待插入的点是不是 尾节点*/
//1.当前节点的后驱指针
currNodep->suffix = newNodep;
//2.新节点的前驱指针
if(currNodep == head)
newNodep->prior = NULL;
else
newNodep->prior = currNodep;
//3.新节点的后驱指针
newNodep->suffix = nextp;
//4.下一个节点的前驱指针
if(nextp == NULL)//到了尾节点处,则将头节点的前驱指向该尾节点,这是双向链表的结构精髓所在
head->prior = newNodep;
else
nextp->prior = newNodep;
#else
if(nextp != NULL)
{
//one not in the tail
newNodep->suffix = nextp;
currNodep->suffix = newNodep;
if(currNodep != head)// not the head
{
newNodep->prior = currNodep;
}
else// currnode is head
{
newNodep->prior = NULL;
}
nextp->prior = newNodep;
}
else
{
//in the tail
currNodep->suffix = newNodep;
if(currNodep != head)//not the head
{
newNodep->prior = currNodep;
}
else//is the head
{
head->prior = newNodep;
newNodep->prior = NULL;
}
newNodep->suffix = NULL;
}
#endif
returntrue;
}

  

删除某个节点

/*删除某个节点*/
bool deleteNode(DOUBLE_LINK *head, DOUBLE_LINK *item)
{
_ASSERT(head != NULL);
_ASSERT(item != NULL);
DOUBLE_LINK *currentNodep = NULL;
DOUBLE_LINK *nextp = NULL;
for(currentNodep = head;(nextp = currentNodep->suffix)!= NULL; currentNodep = nextp)
{
if(nextp == item)
{
/*当前节点为头结点时,这一点很重要*/
if(currentNodep == head)// the head
{
currentNodep->prior = NULL;
currentNodep->suffix = nextp->suffix;
free(nextp);
nextp = NULL;
break;
}
//最后一个节点时
elseif(nextp->suffix == NULL)// the tail
{
currentNodep->suffix = NULL;
free(nextp);
nextp = NULL;
break;
}
else// the mid
{
DOUBLE_LINK *tmp = nextp->suffix;
currentNodep->suffix = nextp->suffix;
nextp->prior = currentNodep;
free(nextp);
nextp = tmp;
}
}
}
returntrue;
}

  

删除节点函数优化

bool deleteNode_opt(DOUBLE_LINK *head, DOUBLE_LINK *item)
{
_ASSERT(head != NULL);
_ASSERT(item != NULL);
//要删除第一个节点
if(item == head->suffix)
{
head->suffix = item->suffix;
item->suffix->prior = NULL;
}
//要删除最后一个节点
elseif(item == head->prior)
{
head->prior = item->prior;
item->prior->suffix = NULL;
}
else
{
item->prior->suffix = item->suffix;
item->suffix->prior = item->prior;
}
free(item);
item = NULL;
returntrue;
}

  

打印函数

void printAllNode(DOUBLE_LINK *head)
{
_ASSERT(head != NULL);
DOUBLE_LINK *currentNodep = NULL;
DOUBLE_LINK *nextNodep = NULL;
std::cout <<"Node data is: ";
for(currentNodep = head;(nextNodep = currentNodep->suffix)!= NULL; currentNodep = nextNodep)
{
std::cout << nextNodep->data<<" ";
}
std::cout << std::endl;
}

  

转载于:https://www.cnblogs.com/Stultz-Lee/p/6847475.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值