2双向链表表循环链表有序链表的常见操作.docx

上传人:b****6 文档编号:3729467 上传时间:2022-11-25 格式:DOCX 页数:13 大小:17.38KB
下载 相关 举报
2双向链表表循环链表有序链表的常见操作.docx_第1页
第1页 / 共13页
2双向链表表循环链表有序链表的常见操作.docx_第2页
第2页 / 共13页
2双向链表表循环链表有序链表的常见操作.docx_第3页
第3页 / 共13页
2双向链表表循环链表有序链表的常见操作.docx_第4页
第4页 / 共13页
2双向链表表循环链表有序链表的常见操作.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

2双向链表表循环链表有序链表的常见操作.docx

《2双向链表表循环链表有序链表的常见操作.docx》由会员分享,可在线阅读,更多相关《2双向链表表循环链表有序链表的常见操作.docx(13页珍藏版)》请在冰豆网上搜索。

2双向链表表循环链表有序链表的常见操作.docx

2双向链表表循环链表有序链表的常见操作

数据结构面试之二——双向链表表、循环链表、有序链表的常见操作

题注:

《面试宝典》有相关习题,但思路相对不清晰,排版有错误,作者对此参考相关书籍和自己观点进行了重写,供大家参考。

二、双向链表

双向链表的建立是在单链表的基础上,多了一个指向前驱的指针back。

其他的操作类似,注意点就是在双向链表的操作,尤其插入、删除操作中需要修改两个指针的指向,一个是back指针,一个是next指针。

1.双向链表的构建【前面插入】

构建双向链表注意点:

1)修改first指针(头指针)的指向。

2)修改back、next指针。

//反向表头插入,从前面插入...

template

nodeType*doublyLinkedList:

:

buildListBackward()

{

nodeType*newNode;

intnum;

cout<<"Enteralistofintegerendwith-999."<

cin>>num;

while(num!

=-999)

{

//..add

newNode=newnodeType;

newNode->info=num;

newNode->next=NULL;

newNode->back=NULL;

if(first==NULL)

{

first=newNode;

}

else

{

newNode->next=first;

first->back=newNode;

first=newNode;

}

cin>>num;

}

returnfirst;

}

2.双向链表的插入节点【此处考虑插入后保证有序,直接插入排序】

节点的插入同单链表,依然需要考虑多种因素。

分以下几类:

1)双向链表为空,“提示信息”并返回。

2)双向链表非空,待插入节点的元素值小于first节点,需要修改first指针。

3)双向链表非空,待插入节点的元素值为链表中间的节点,需修改back、next指向。

4)双向链表非空,待插入节点在最末尾节点以后,修改最末节点的指针。

//双向不循环链表

template

voiddoublyLinkedList:

:

insertNode(constType&insertItem)//new

{

nodeType*current;

nodeType*trailCurrent;

nodeType*newNode;

boolfound=false;

newNode=newnodeType;

newNode->info=insertItem;

newNode->next=NULL;

newNode->back=NULL;

//case1:

空表

if(first==NULL)

{

first=newNode;

}

else

{

current=first;

while(current!

=NULL)

{

if(current->info>=insertItem)

{

found=true;

break;

}

else

{

trailCurrent=current;

current=current->next;

}

}

//case2:

第一个节点

if(current==first)

{

current->next=newNode;

newNode->back=current;

}

else

{

//case3:

中间节点

if(current!

=NULL)

{

newNode->next=trailCurrent->next;

current->back=newNode;

trailCurrent->next=newNode;

newNode->back=trailCurrent;

}

else//case4:

最后一个节点前

{

trailCurrent->next=newNode;

newNode->back=trailCurrent;

}//endcase4

}

}

}

3.双向链表的删除节点

同样需要考虑以下几点:

1) 链表为空,“提示信息”并返回。

2) 链表非空,查找删除的元素在链表是否存在。

是的话,found=true;否的话,found=false。

3) 如果没有找到包含查找元素的节点,“错误提示”并返回。

4) 如果找到,主要节点位置。

如果是头节点或末尾节点主要修改first指针,及节点的back、next指向;如果不是头节点或者末尾节点就是中间节点,主要back、next的指向,完成插入。

template

voiddoublyLinkedList:

:

deleteNode(constType&deleteItem)//new

{

nodeType*current=newnodeType;

nodeType*trailCurrent;

boolfound=false;

//case1:

空表

if(first==NULL)

{

cout<<"TheListisNULL!

"<

exit

(1);

}

else

{

current=first;

while(current!

=NULL)

{

if(current->info==deleteItem)

{

found=true;

break;

}

else

{

trailCurrent=current;

current=current->next;

}

}

if(found)

{

//case2:

第一个节点

if(current==first)

{

first=current->next;

deletecurrent;

}

else

{

//case3:

中间节点

if(current!

=NULL)

{

if(current->next!

=NULL)//case3.1:

要删除的是中间节点.

{

trailCurrent->next=current->next;

current->next->back=trailCurrent;

deletecurrent;

}

else

{

trailCurrent->next=NULL;//case3.2:

要删除的为最后一个节点.

deletecurrent;

}

}

}//endelse

}//endif

else

{

cout<<"Theelem"<

"<

链表中无此节点.

}

}//endelse

}//end

三、循环链表

      循环链表能保障从每一个节点出发都能检索链表。

即:

last指针的指向不再为空,而是指向了first(头结点)。

      循环链表在构建链表、查找元素、插入、删除、操作中要注意修改末尾节点指针的指向,保证链表的循环。

1.      前插式构建循环链表

【思路】:

每次在first指针前面插入节点;插入每个节点后注意修改last->link的指向。

template

voidcycleList:

:

bulidCycListBackward()//前插构造循环链表.

{

TypenewItem;

while(cin>>newItem,newItem!

=-999)

{

nodeType*newNode=newnodeType;

newNode->info=newItem;

newNode->link=NULL;

if(first==NULL)

{

first=newNode;

last=newNode;

first->link=first;

last->link=first;

}

else

{

newNode->link=first;

last->link=newNode;

first=newNode;

}

}

cout<<"输入完毕!

"<

}

2.      循环链表插入元素[后插入]

【思路】:

同构造循环链表,每次在last指针后面插入节点;插入每个节点后注意修改last->link的指向。

//只在last末尾插入

template

voidcycleList:

:

insertCycList(constType&newItem)

{

nodeType*newNode=newnodeType;

newNode->info=newItem;

newNode->link=NULL;

if(first==NULL)//链表为空...

{

first=newNode;

last=newNode;

first->link=first;

last->link=first;

}

else//链表非空...

{

last->link=newNode;

newNode->link=first;

last=newNode;

}

cout<

"<

}

3.      删除循环链表节点

考虑到是否为空链表、删除元素在链表中不存在、及节点存在(节点的位置可能为共分头、中间、尾),所以分为以下5种情况分别处理。

:

//case1:

链表为空。

//case2:

链表非空,删除节点为头节点。

//case3:

链表非空,删除节点为尾节点。

//case4:

链表非空,删除节点为中间节点。

//case5:

链表非空,不存在=deleteItem的节点。

template

voidcycleList:

:

delCycList(constType&deleteItem)

{

nodeType*current=newnodeType;

nodeType*trailCurrent=newnodeType;

nodeType*temp;

boolfound=false;

if(first==NULL)

{

cout<<"TheListisEmpty!

"<

return;

}

if(first->info==deleteItem)//case2

{

temp=newnodeType;

temp=first;

first=first->link;

last->link=first;

cout<<"Thenodehas"<

"<

deletetemp;

return;

}

else//cas3,case4.需要查找后定位。

{

current=first->link;

while(!

found&¤t!

=first)

{

if(current->info==deleteItem)

{

found=true;

break;

}

else

{

trailCurrent=current;

current=current->link;

}

}//endwhile

if(found)

{

temp=newnodeType;

if(current==last)//case3

{

temp=last;

trailCurrent->link=last->link;//last->link=first

last=trailCurrent;

}

else

{

temp=current;

trailCurrent->link=current->link;

}

cout<<"TheElem:

"<

"<

deletetemp;

}

else

{

cout<<"TheElem:

"<

"<

}

}//endelse

}

四、有序链表

注意:

此处有序链表无非是在之前的一、单链表的操作的基础上,在插入元素的时候,按顺序插入,考虑的排序。

为了体现有序的特点,特通过递归实现了有序链表的逆序打印。

关于有序链表或者链表的非递归实现,可以通过栈实现。

下一节会分析并实现。

1.      有序链表的插入

考虑以下三种情况:

1) 当前链表为空;

2) 当前链表非空,要插入的元素值小于头结点的元素值;

3) 当前链表非空,要插入的元素值大于头结点的元素值,可以考虑找到第一个大于其的元素则停止搜索,插入其前即可。

template

voidorderedLinkedListType:

:

insertNode(constType&newItem)

{

nodeType*current;

nodeType*trailCurrent;

nodeType*newNode;

boolfound=false;

newNode=newnodeType;

newNode->info=newItem;

newNode->link=NULL;

if(first==NULL)//case1:

链表为空.

{

first=newNode;

last=first;

}

else

{

current=first;

while(!

found&¤t!

=NULL)//循环查找

{

if(current->info>=newItem)

{

found=true;

break;

}

else

{

trailCurrent=current;

current=current->link;

}

}//endwhile

//first特殊处理..

if(current==first)//case2:

新插入的元素小于first节点的元素值..

{

newNode->link=first;

first=newNode;

}

else//其他..

{

newNode->link=current;//case3:

新插入的节点在非first位置

trailCurrent->link=newNode;

}

}//endelse

}

2.      递归实现有序链表的逆序打印

template

voidorderedLinkedListType:

:

printListReverse()const//逆序打印.

{

reversePrint(first);

cout<

}

//递归实现单链表的逆序打印.

template

voidorderedLinkedListType:

:

reversePrint(nodeType*current)const//逆序打印

{

if(current!

=NULL)

{

reversePrint(current->link);

cout<info<<"\t";

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1