知识大全 常见面试题之链表操作

Posted 面试

篇首语:最是人间留不住,朱颜辞镜花辞树。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 常见面试题之链表操作相关的知识,希望对你有一定的参考价值。

链表的常见操作

链表是数据结构的重要内容 在计算机程序中应用广泛 同时也是各公司笔试题目的重点

  以下简单实现了链表的一些操作 包括创建 增加节点 删除节点 单链表逆置 合并有序链表等

一 链表创建

  链表主要有三种形式 包括单链表 双链表和循环链表

  单链表每个节点只包含一个后驱指针 双链表节点同时包含一个前驱指针和一个后驱指针 循环链表的尾节点的后驱指向头节点

  代码如下

/*单链表节点结构*/ typedef struct NodeType char elem; NodeType*next; Node;

/*双链表节点结构*/ typedef struct 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( ) 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( ) 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( ) 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;

/* 输出链表 */ void PrintList(Node*head) Node* current=head >next; cout<<&# ;\\n List are:&# ;; while(NULL!= current) if(NULL!= current >elem) cout<<se( )<<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;/*暂存下一个节点*/ /*把当前节点插入到head节点后*/ curr >next=head >next; head >next=curr;

curr=temp;/*移动至下一个节点*/

return head;

四 求单链表中间节点

  在笔试题中比较常见 通常题目描述是 给出一个单链表 不知道节点N的值 怎样只遍历一次就可以求出中间节点

  算法描述 设立两个指针p p p 每次移动 个节点位置 p 每次移动 个节点位置 当p 移动到尾节点时 p 指向中间节点

  代码如下

求中间节点

/*求中间节点*/ Node* MiddleNode(Node*head) if(NULL== head) return head; if(NULL== head >next) return head >next;

Node*p *p ; p =head; p =head;

while(p >next) /*p 节点移动 个节点位置*/ p =p >next; if(p >next)/*判断p 后驱节点是否存在 存在则再移动一次*/ p =p >next; /*p 节点移动 个节点位置*/ p =p >next;

return p ;

五 合并有序单链表

  问题描述 合并 个有序单链表 合并后的链表也是排好序的

  算法描述 对链表A中的每一个节点元素 查找其在链表B中的插入位置 并在B中插入该元素

  代码如下

合并有序单链表/*合并有序单链表*/ Node* MergeList(Node* h Node* h ) if(NULL== h || NULL== h ) return h ; if(NULL== h >next ) return h ; if(NULL== h >next) return h ;

Node* curr *curr *prev *temp; prev =h ;/*链表 的前驱节点*/ curr =h >next;/*链表 的当前节点*/ curr =h >next;/*链表 的当前节点*/ temp=h ; while(curr ) while(curr && curr >elem< curr >elem)/*链表 指针移动至大或等于链表 当前元素的位置*/ prev =curr curr =curr >next;

/*在链表 中插入链表 的当前元素*/ temp=curr >next;/*暂存链表 的下一个节点*/ prev >next=curr ; curr >next=curr ;

/*链表 移动至新节点*/ curr =curr ; /*链表 移动至下一个节点*/ curr =temp;

return h ;

六 判断链表是否有环

  判断链表是否有环即是判断链表是否为循环链表 算法较为简单 一次遍历判断尾指针是否指向头指针即可

  代码如下

/*判断链表是否有环(循环链表)*/ 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全部代码如下

/* * 作者 达闻东 * 修改日期 : * 描述 实现链表的常见操作 * */ #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( ) 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<<se( )<<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;/*暂存下一个节点*/ /*把当前节点插入到head节点后*/ 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*p *p ; p =head; p =head;

while(p >next) /*p 节点移动 个节点位置*/ p =p >next; if(p >next)/*判断p 后驱节点是否存在 存在则再移动一次*/ p =p >next; /*p 节点移动 个节点位置*/ p =p >next;

return p ;

/*=============================================================================*/

/*合并有序单链表*/ Node* MergeList(Node* h Node* h ) if(NULL== h || NULL== h ) return h ; if(NULL== h >next ) return h ; if(NULL== h >next) return h ;

Node* curr *curr *prev *temp; prev =h ;/*链表 的前驱节点*/ curr =h >next;/*链表 的当前节点*/ curr =h >next;/*链表 的当前节点*/ temp=h ; while(curr ) while(curr && curr >elem< curr >elem)/*链表 指针移动至大或等于链表 当前元素的位置*/ prev =curr curr =curr >next;

/*在链表 中插入链表 的当前元素*/ temp=curr >next;/*暂存链表 的下一个节点*/ prev >next=curr ; curr >next=curr ;

/*链表 移动至新节点*/ curr =curr ; /*链表 移动至下一个节点*/ curr =temp;

return h ;

/*=============================================================================*/

/*创建双链表*/ 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( ) 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;

/*=============================================================================*/ /*输出双链表*/ void PrintDoubleList(DNode*head) if(NULL== head) return;

DNode* p; p=head; cout<<&# ;\\n DoubleList are:&# ;; while(p >next) p=p >next; if(p >elem) cout<<se( )<<p >elem;

cout<<&# ;\\n DoubleList are:&# ;; while(p >prev) if(p >elem) cout<<se( )<<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( ) 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; /*=============================================================================*/

/*判断链表是否有环(循环链表)*/ 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* head *head ; DNode* dHead; char ch; head= NULL; head =NULL; head =NULL; dHead=NULL;

//head=(Node*) malloc ( sizeof( Node) ); //head >next = NULL;

//创建单链表 head=CreateList(head); PrintList(head);

head =CreateList(head ); PrintList(head );

//插入节点

cout<<&# ;\\n input elem to insert:&# ;; cin>>ch; InsertNode(head ch); PrintList(head);

//删除节点

cout<<&# ;\\n input elem to delete:&# ;; cin>>ch; DeleteNode(head ch); PrintList(head);

//单链表逆置

head=ReverseList(head); cout<<&# ;\\n Reversed !&# ;; PrintList(head);

//求中间节点

p=MiddleNode(head); cout<<&# ;\\n Middle Node is:&# ;; cout<<p >elem<<endl;

//合并有序单链表

MergeList(head head ); cout<<&# ;\\n Merged!&# ;; PrintList(head);

//创建双链表

dHead=DoubleList(dHead); PrintDoubleList(dHead);

cha138/Article/program/sjjg/201404/30581

相关参考

知识大全 2009年常见面试题精选及总结

1."Tellmeaboutyourself".简要介绍你自己。2."Whyareyouinterestedinthisposition?"你为什么对这份工作感兴趣?3."Whatareyourstr

知识大全 数据结构之链栈

  链栈栈的链式存储结构称为链栈     链栈是运算受限的单链表它的插入和删除被限制在表头位置上进行栈顶指针就是链表的头指针它唯一确定一个链栈  链栈上实现的基本运算  置空栈   &nbs

知识大全 《数据结构》哈工大2013年实践上机试题

  随机产生个整数在计算机内建立有序链表并输出该链表#includeioh  #includestdlibh  #includestdioh  #includemathh  typedefstruct

知识大全 北京邮电大学2013年考研试题[6]

  已知以二叉链表表示的二叉树中有值为eee的三个结点下面的算法是判断e是否为e和e的共同祖先请在空格处填上相应的语句或表达式  求以二叉链表表示的二叉树中叶子结点的个数在求值过程中将树中所有结点的左

知识大全 全国2013年1月数据结构导论试题

  一单项选择题(本大题共小题每小题分共分)  在每小题列出的四个备选项中只有一个是符合题目要求的请将其代码填写在题后的括号内错选多选或未选均无分  数据的四种基本逻辑结构是指()  A数组链表树图形

知识大全 数据结构之链队列

基本概念  队列的链式存储结构称为链队列它是限制仅在表头删除和表尾插入的单链表  一个链队列由一个头指针和一个尾指针唯一地确定  实现链队列上的六种基本运算    置空队      判队空 

知识大全 我和男友两年异地恋,现在感觉感情淡了,我们放假也不常见面,家长不知道,我们能长久吗

我和男友两年异地恋,现在感觉感情淡了,我们放假也不常见面,家长不知道,我们能长久吗嗯,这是很正常的事,异地恋的男女谈的时间长了都有感觉淡了的感觉,这是因为人都有新鲜感,刚开始对对方有新鲜感很想接近对方

知识大全 第一部分 线性存储结构[5]

   试题  【年真题】    (分)己知一个带有表头结点的单链表夕结点结构为data…link假设该链表只给出了头指针list在不改变链表的前提下请设计一个尽可能高效的

知识大全 双方父母见面是订婚吗

结婚之前,让父母见面是常有的事儿。那么双方父母见面是订婚吗,要谁提,何时见面合适,聊什么呢?这里有你要的答案。

知识大全 哈尔滨工业大学2013年数据结构考研试题答案[1]

  哈尔滨工业大学年考研试题数据结构答案  一名词解释  抽象数据型一个数学模型和在该模型上定义的操作集合的总称  算法的时间复杂性算法中基本操作重复执行的次数是问题规模n的某个函数f(n)算法的时间