链表是数据结构的重要内容,在计算机程序中应用广泛,同时也是各公司笔试题目的重点。
以下简单实现了链表的一些操作,包括创建、增加节点、删除节点、单链表逆置、合并有序链表等。
一、链表创建
链表主要有三种形式,包括单链表、双链表和循环链表。
单链表每个节点只包含一个后驱指针,双链表节点同时包含一个前驱指针和一个后驱指针,循环链表的尾节点的后驱指向头节点。
代码如下:
-
- typedef structNodeType
- {
- char elem;
- NodeType*next;
- }Node;
-
-
- typedef structDNodeType
- {
- char elem;
- DNodeType*next;
- DNodeType*prev;
- }DNode;
-
-
-
-
- Node* CreateList(Node*head)
- {
- if(NULL== head)
- head=(Node*)malloc(sizeof(Node)),
- head->next=NULL;
-
- Node*current=head ,*temp;
- char ch;
-
- while(1)
- {
- cout<<"\n input elem:";
- cin>>ch;
- if('#' == ch)
- break;
- temp=(Node*) malloc (sizeof(Node) );
- temp->elem=ch;
- temp->next=NULL;
- current->next=temp;
- current=temp;
-
- }
-
- return head;
- }
-
-
-
-
- DNode* DoubleList(DNode*head)
- {
- if(NULL== head)
- head=(DNode*)malloc(sizeof(DNode)) , head->prev=NULL ,head->next=NULL;
-
- DNode*current=head ,*temp;
- char ch;
-
- while(1)
- {
- cout<<"\n input elem:";
- cin>>ch;
- if('#' == ch)
- break;
- temp=(DNode*) malloc (sizeof(DNode) );
- temp->elem=ch;
- temp->next=NULL;
- current->next=temp;
- temp->prev=current;
- current=temp;
-
- }
-
- return head;
- }
-
-
-
-
- Node* CycleList(Node*head)
- {
- if(NULL== head)
- head=(Node*)malloc(sizeof(Node)),head->next=NULL;
-
- Node*current=head ,*temp;
- char ch;
-
- while(1)
- {
- cout<<"\n input elem:";
- cin>>ch;
- if('#' == ch)
- break;
- temp=(Node*) malloc (sizeof(Node) );
- temp->elem=ch;
- temp->next=NULL;
- current->next=temp;
- current=temp;
-
- }
- current->next=head;
- return head;
- }
二、链表操作
包括单链表的增加节点、删除节点、输出链表等
-
- Node*InsertNode(Node*head ,char elem)
- {
- if( NULL== head|| NULL== elem )
- return head;
-
- Node*current=head->next;
- Node*prev=head;
- Node*temp;
-
- while(current)
- {
- prev=current;
- current=current->next;
- }
-
- temp=(Node*)malloc(sizeof(Node));
- temp->elem=elem;
- temp->next=NULL;
- prev->next=temp;
-
- return head;
- }
-
-
- Node*DeleteNode(Node*head,char elem)
- {
- if(NULL== head|| NULL== elem)
- return head;
- if(NULL== head->next)
- return head;
-
- Node*prev,*current;
- prev=head;
- current=head->next;
-
- while(current)
- {
- if(current->elem== elem)
- {
- prev->next=current->next;
- free(current);
- return head;
- }
- prev=current;
- current=current->next;
- }
-
- return head;
-
- }
-
- void PrintList(Node*head)
- {
- Node* current=head->next;
- cout<<"\n List are:";
- while(NULL!= current)
- {
- if(NULL!= current->elem)
- cout<<setw(5)<<current->elem;
- current=current->next;
- }
-
- cout<<"\n";
- }
三、单链表逆置
单链表逆置在各公司的笔试题中比较常见,以下是其中一种实现。
算法描述:将链表中每一个节点插入到头结点之后。
代码如下:
-
- Node*ReverseList(Node*head)
- {
- if(NULL== head)
- return head;
- if(NULL== head->next)
- return head;
- if(NULL== head->next->next)
- return head;
-
- Node*curr=head->next;
- head->next=NULL;
- Node*temp;
-
- while(curr)
- {
- temp=curr->next;
-
- curr->next=head->next;
- head->next=curr;
-
- curr=temp;
- }
-
- return head;
- }
四、求单链表中间节点
在笔试题中比较常见,通常题目描述是:给出一个单链表,不知道节点N的值,怎样只遍历一次就可以求出中间节点。
算法描述:设立两个指针p1,p2,p1每次移动1个节点位置,p2每次移动2个节点位置,当p2移动到尾节点时,p1指向中间节点。
代码如下:
-
- Node* MiddleNode(Node*head)
- {
- if(NULL== head)
- return head;
- if(NULL== head->next)
- return head->next;
-
- Node*p1,*p2;
- p1=head;
- p2=head;
-
- while(p2->next)
- {
-
- p2=p2->next;
- if(p2->next)
- p2=p2->next;
-
- p1=p1->next;
-
- }
- return p1;
- }
五、合并有序单链表
问题描述:合并2个有序单链表,合并后的链表也是排好序的。
算法描述:对链表A中的每一个节点元素,查找其在链表B中的插入位置,并在B中插入该元素。
代码如下:
-
- Node* MergeList(Node*h1,Node* h2)
- {
- if(NULL== h1|| NULL== h2)
- return h1;
- if(NULL== h1->next )
- return h2;
- if(NULL== h2->next)
- return h1;
-
- Node* curr1,*curr2,*prev1,*temp;
- prev1=h1;
- curr1=h1->next;
- curr2=h2->next;
- temp=h2;
- while(curr2)
- {
- while(curr1&&curr1->elem< curr2->elem)
- prev1=curr1,curr1=curr1->next;
-
-
- temp=curr2->next;
- prev1->next=curr2;
- curr2->next=curr1;
-
-
- curr1=curr2;
-
- curr2=temp;
- }
-
- return h1;
- }
六、判断链表是否有环
判断链表是否有环即是判断链表是否为循环链表,算法较为简单,一次遍历判断尾指针是否指向头指针即可。代码如下:
-
- bool IsCycleList(Node*head)
- {
- if(NULL== head)
- return false;
- if(NULL== head->next)
- return false;
- Node*current=head->next;
- while(current)
- {
- if(head== current->next)
- return true;
- current=current->next;
- }
- return false;
- }
七、总结及源文件
以上实现了链表的一些常见操作,源文件LinkList.cpp全部代码如下:
/*
* 作者: 达闻东
* 修改日期:2010-04-28 17:10
* 描述: 实现链表的常见操作
*/
- #include<iostream>
- #include<iomanip>
- using namespace std;
-
-
- typedefstruct NodeType
- {
- char elem;
- NodeType*next;
- }Node;
-
-
- typedefstruct DNodeType
- {
- char elem;
- DNodeType*next;
- DNodeType*prev;
- }DNode;
/*创建链表*/
- Node* CreateList(Node*head)
- {
- if(NULL== head)
- head=(Node*)malloc(sizeof(Node)),
- head->next=NULL;
-
- Node*current=head ,*temp;
- char ch;
-
- while(1)
- {
- cout<<"\n input elem:";
- cin>>ch;
- if('#' == ch)
- break;
- temp=(Node*) malloc (sizeof(Node) );
- temp->elem=ch;
- temp->next=NULL;
- current->next=temp;
- current=temp;
-
- }
-
- return head;
- }
/*输出链表*/
- void PrintList(Node*head)
- {
- Node* current=head->next;
- cout<<"\n List are:";
- while(NULL!= current)
- {
- if(NULL!= current->elem)
- cout<<setw(5)<<current->elem;
- current=current->next;
- }
- cout<<"\n";
- }
/*插入节点*/
- Node*InsertNode(Node*head,char elem)
- {
- if( NULL== head|| NULL== elem)
- return head;
-
- Node*current=head->next;
- Node*prev=head;
- Node*temp;
-
- while(current)
- {
- prev=current;
- current=current->next;
- }
-
- temp=(Node*) malloc(sizeof(Node) );
- temp->elem=elem;
- temp->next=NULL;
- prev->next=temp;
-
- return head;
- }
/*删除节点*/
- Node*DeleteNode(Node*head,char elem)
- {
- if(NULL== head|| NULL== elem)
- return head;
- if(NULL== head->next)
- return head;
-
- Node*prev,*current;
- prev=head;
- current=head->next;
-
- while(current)
- {
- if(current->elem== elem)
- {
- prev->next=current->next;
- free(current);
- return head;
- }
- prev=current;
- current=current->next;
- }
- return head;
- }
/*单链表逆置*/
- Node*ReverseList(Node*head)
- {
- if(NULL== head)
- return head;
- if(NULL== head->next)
- return head;
- if(NULL== head->next->next)
- return head;
-
- Node*curr=head->next;
- head->next=NULL;
- Node*temp;
-
- while(curr)
- {
- temp=curr->next;
-
- curr->next=head->next;
- head->next=curr;
-
- curr=temp;
- }
- return head;
- }
/*求中间节点*/
- Node* MiddleNode(Node*head)
- {
- if(NULL== head)
- return head;
- if(NULL== head->next)
- return head->next;
-
- Node*p1,*p2;
- p1=head;
- p2=head;
-
- while(p2->next)
- {
-
- p2=p2->next;
- if(p2->next)
- p2=p2->next;
-
- p1=p1->next;
- }
- return p1;
- }
/*合并有序单链表*/
- Node* MergeList(Node* h1,Node* h2)
- {
- if(NULL== h1|| NULL== h2)
- return h1;
- if(NULL== h1->next)
- return h2;
- if(NULL== h2->next)
- return h1;
-
- Node* curr1,*curr2,*prev1,*temp;
- prev1=h1;
- curr1=h1->next;
- curr2=h2->next;
- temp=h2;
- while(curr2)
- {
- while(curr1&& curr1->elem< curr2->elem)
-
- prev1=curr1,curr1=curr1->next;
-
-
- temp=curr2->next;
- prev1->next=curr2;
- curr2->next=curr1;
-
-
- curr1=curr2;
-
- curr2=temp;
- }
- return h1;
- }
/*创建双链表*/
- DNode* DoubleList(DNode*head)
- {
- if(NULL== head)
- head=(DNode*)malloc(sizeof(DNode)) ,head->prev=NULL , head->next=NULL;
-
- DNode*current=head ,*temp;
- char ch;
-
- while(1)
- {
- cout<<"\n inputelem:";
- cin>>ch;
- if('#' == ch)
- break;
- temp=(DNode*) malloc (sizeof(DNode) );
- temp->elem=ch;
- temp->next=NULL;
- current->next=temp;
- temp->prev=current;
- current=temp;
- }
- return head;
- }
/*输出双链表*/
- void PrintDoubleList(DNode*head)
- {
- if(NULL== head)
- return;
-
- DNode* p;
- p=head;
- cout<<"\n DoubleListare:";
- while(p->next)
- {
- p=p->next;
- if(p->elem)
- cout<<setw(5)<<p->elem;
-
- }
-
- cout<<"\n DoubleListare:";
- while(p->prev)
- {
- if(p->elem)
- cout<<setw(5)<<p->elem;
- p=p->prev;
- }
- }
/*创建循环链表*/
- Node* CycleList(Node*head)
- {
- if(NULL== head)
- head=(Node*)malloc(sizeof(Node)),head->next=NULL;
-
- Node*current=head ,*temp;
- char ch;
-
- while(1)
- {
- cout<<"\n inputelem:";
- cin>>ch;
- if('#' == ch)
- break;
- temp=(Node*) malloc (sizeof(Node) );
- temp->elem=ch;
- temp->next=NULL;
- current->next=temp;
- current=temp;
-
- }
- current->next=head;
- return head;
- }
/*判断链表是否有环(循环链表)*/
- bool IsCycleList(Node*head)
- {
- if(NULL== head)
- return false;
- if(NULL== head->next)
- return false;
- Node*current=head->next;
- while(current)
- {
- if(head== current->next)
- return true;
- current=current->next;
- }
- return false;
- }
- int main()
- {
- Node* head,*p;
- Node* head2,*head3;
- DNode* dHead;
- char ch;
- head= NULL;
- head2=NULL;
- head3=NULL;
- dHead=NULL;
-
-
-
-
-
- head=CreateList(head);
- PrintList(head);
-
- head2=CreateList(head2);
- PrintList(head2);
-
-
- cout<<"\n input elem toinsert:";
- cin>>ch;
- InsertNode(head,ch);
- PrintList(head);
-
-
- cout<<"\n input elem todelete:";
- cin>>ch;
- DeleteNode(head,ch);
- PrintList(head);
-
-
- head=ReverseList(head);
- cout<<"\n Reversed !";
- PrintList(head);
-
-
- p=MiddleNode(head);
- cout<<"\n Middle Nodeis:";
- cout<<p->elem<<endl;
-
-
- MergeList(head,head2);
- cout<<"\n Merged!";
- PrintList(head);
-
-
- dHead=DoubleList(dHead);
- PrintDoubleList(dHead);
-
-
- head3=CycleList(head3);
- cout<<IsCycleList(head3);
- return 0;
- }
(达闻东) |