zoukankan      html  css  js  c++  java
  • C++面试笔记--单链表

    1、编程实现单链表删除节点。

          解析:如果删除的是头节点,如下图:

    QQ截图20111106194807

         则把head指针指向头节点的下一个节点。同时free p1,如下图所示:

    QQ截图20111106194959

        如果删除的是中间节点,如下图所示:

    QQ截图20111106195116

        则用p2的next指向p1的next同时,free p1 ,如下图所示:

    QQ截图20111106195254

     

    2、编写程序实现单链表的插入。

          解析:单链表的插入,如下图所示:

    QQ截图20111106201812

     

         如果插入在头结点以前,则p0的next指向p1,头节点指向p0,如下图所示:

    QQ截图20111106202019

     

        如果插入中间节点,如下图所示:

    QQ截图20111106202158

        则先让p2的next指向p0,再让p0指向p1,如下图所示:

    QQ截图20111106202318

        如果插入尾节点,如下图所示:

    QQ截图20111106202516

     

        则先让p1的next指向p0,再让p0指向空,如下图所示:

    QQ截图20111106202635

      

    3、编写实现单链表的逆置。

         解析:单链表模型如下图所示:

        进行单链表逆置,首先要让p2的next指向p1,如下图所示:

    QQ截图20111106213740

     

        再由p1指向p2,p2指向p3,如下图所示:

    QQ截图20111106213748

     

        让后重复p2的next指向p1,p1指向p2,p2指向p3。

    QQ截图20111106213759

     

      

      1 #include<iostream>
      2 using namespace std;
      3 typedef struct Student{
      4     int data;
      5     struct student *next;//结构体重如果没有用typedef定义结构体,那么想要声明一个结构体的变量,就需要加上struct
      6     
      7 }node;
      8 
      9 node *creat(){
     10     /*① 建立头结点
     11       ② 循环输入节点值,0停止输入,其他则继续输入
     12       ③ 插入一个值,新建一个节点存储该值,赋值操作,指针修改操作
     13         上一个节点的next指向新建立的节点,临时指针指向当前节点方便递增操作
     14       ④ 返回一个头结点,该节点不为空
     15     */
     16     node *head,*p,*s;//头结点,p临时头节点,s为新建立的节点
     17     int x,cycye=1;//输入停止变量
     18     head=(node*)malloc(sizeof(node));//建立头结点
     19     p=head;
     20     while(cycle){
     21         cout<<"请输入链表数据:"<<endl;
     22         cin>>x;
     23         if(x!=0){//当输入不为0,继续输入
     24             s=(node*)malloc(sizeof(node));//S为新建立的节点
     25             s->data=x;
     26             cout<<s->data<<endl;
     27             p->next=s;
     28             p=s;//临时指针递增
     29         }
     30         else{
     31             cycle=0;//停止输入
     32         }
     33         p->next=NULL;//指针指向链表尾端
     34         cout<<"    yyy"<<head->next->data<<endl;
     35         head=head->next;
     36         return (head);
     37     }
     38 }
     39 //打印链表
     40 void print(node *head){
     41     /* ① 该链表为空,不输出。
     42        ② 该链表不为空且不止一个节点:头结点没有值,则从头结点的下一个节点开始输出
     43     */
     44     node *tem_node;//临时节点
     45     tem_node=head;
     46     //这里还要输出链表长度
     47     int length=length(head);
     48     cout<<"该链表长度为:"<<length<<endl;
     49     
     50     if(head!=NULL){
     51         tem_node=tem_node->next;//因为该头结点没有值,所以要指向下一个
     52     }
     53     while(tem_node!=NULL){
     54         cout<<"节点值:"<<tem_node->data<<endl;
     55         tem_node=tem_node->next;
     56     }
     57 }
     58 //删除节点
     59 node *remove(node *head,int num){
     60     /*① 删除头结点:把头结点的指针指向下一个节点,再把头结点移除
     61       ② 删除中间节点:前驱节点的next指向删除节点的next
     62     */
     63     node *p1,*p2;
     64     p1=head;
     65     //找到删除位置
     66     while(num!=p1->data &&p1->next!=NULL){//删除的值不为头结点值,并且头结点不为空
     67         p2=p1;//删除节点的上一个节点
     68         p1=p1->next;//找到删除节点
     69     }
     70     if(num==p1->data){//如果存在p1节点,删除
     71         if(p1==head){//删除头结点
     72             head=p1->next;
     73             free(p1);
     74         } 
     75         else{
     76             p2->next=p1->next;
     77         }
     78     }
     79     else{
     80         cout<<"不存在值为"<<num<<"的节点!"<<endl;
     81     }
     82     return (head);
     83 }
     84 node *insert(node *head,int num){
     85     /*① 从头部插入:头指针指向插入节点,新插入节点next指向原头结点
     86       ② 从中间插入:插入位置的前一个节点next指向新插入节点,新插入节点nex指向后一个节点
     87       ③ 从尾部插入:和2类似,只是最后是新插入节点next指向NULL
     88     */
     89     node *p1,*p2,*p3;
     90     p2=head;
     91     p1=(node*)malloc(sizeof(node));//新增节点
     92     p1->data=num;
     93     while(p1->data > p2->data && p2->next!=NULL){//找插入点
     94         p3=p2;
     95         p2=p2->next;
     96         //p2是后一个,P3是前一个
     97     }
     98     //判断这个插入的位置
     99     if(p1->data<=p2->data){
    100         if(head==p2){//从头结点插入
    101             p1->next=p2;
    102             head=p1;
    103         }
    104         else {//从中间节点插入
    105             p3->next=p1;
    106             p1->next=p2;
    107         }
    108     }
    109     else{//没有比他大的数,从尾部插入
    110         p2->next=p1;
    111         p1->next=NULL;
    112     }
    113     return (head);
    114 }
    115 //链表排序
    116 node *sort(node *head){
    117     /*冒泡排序法解决*/
    118     node *p,*p2,*p3;
    119     int n;
    120     int temp;
    121     n=length(head);
    122     if(head==NULL ||head->next==NULL)//如果只有一个或者没有节点
    123         return head;
    124     p=head;
    125     for(int j=1;j<n;++j)    {
    126         p=head;
    127         for(int i=0;i<n-j;++i)        {
    128             if(p->data > p->next->data){
    129                 temp=p->data;
    130                 p->data=p->next->data;
    131                 p->next->data=temp;
    132             }
    133             p=p->next;
    134         }
    135     }
    136         return (head);
    137 
    138 }
    139 //链表的转置
    140 node *reverse(node *head){
    141     /**/
    142     node *p1,*p2,*p3;
    143     if(head==NULL || head->next==NULL){
    144         return head;
    145     }
    146     p1=head;
    147     p2=p1->next;
    148     while(p2){
    149         p3=p2->next;
    150         p2->next=p1;
    151         p1=p2;
    152         p2=p3;
    153     }
    154     head->nex=NULL;
    155     head=p1;
    156     return head;
    157 }
    158 //链表测长
    159 int length(node *head){
    160     node *tem_node;
    161     tem_node=head;
    162     int n=0;
    163     while(tem_node!=NULL){
    164         n++;
    165         tem_node=tem_node->next;
    166     }
    167     return n;
    168 }
    169 
    170 int main(){
    171     
    172 }
    View Code

    4、编程实现删除单链表的头元素。

        答案:

        

    1 #include<iostream>
    2 using namespace std;
    3 
    4 void Removehead(node *head){
    5     node * p=head;
    6     head=head->next;
    7     free(p);
    8 }
    View Code

    5、给出一个单链表,不知道节点N的值,怎么只遍历一次就可以求出中间节点,写出算法。

        解析:设立两个指针,比如*p和*q。p每次移动两个位置,即p=p->next->next,q每次移动一个位置,即q=q->next。当p达到最后一个节点时,q就是中间节点了。

        答案:

        

     1 #include<iostream>
     2 using namespace std;
     3 //给出一个单链表,不知道节点N的值,怎么遍历一次就可以求出中间节点
     4 void searchMid(node *head,node *mid){
     5     node *p,*q;
     6     p=head;
     7     q=head;
     8     while(p->next->next!=NULL){
     9         p=p->next->next;//p移动两个位置
    10         q=q->next;//q移动一个位置,这样相当于p走了两倍,q走了一倍就到达了中点
    11         mid=q;
    12     }
    13 }
    View Code

    6、给定一个单向链表,设计一个时间优化并且空间优化的算法,找出该链表的倒数第m个元素。实现您的算法,注意处理相关的出错情况。m定义为当m=0时,返回链表最后一个元素。

        解析:这是一个难题,我们需要的是倒数第m个元素,所以如果我们从某个元素开始,遍历了m个元素之后刚好到达链表末尾,那么这个元素就是要找的元素。也许从链表的尾部倒推回去不是最好的办法,那么我们可以从链表头开始计数。

        思路一:我们可以先一次遍历求出链表的总长度n,然后顺序变量求出第n-m个元素,那么这个就是我们要找的元素了。

        思路二:我们用两个指针,一个当前位置指针p和一个指向第m个元素的指针q,需要确保两个指针之间相差m个元素,然后以同样的速度移动它们,如果当q到达链表末尾时,那么p指针就是指向倒数第m个元素了。

        答案:

        

     1 #include<iostream>
     2 using namespace std;
     3 //思路二
     4 node* search_last_m_num(node *head,int m){
     5     if(head==NULL)
     6         return NULL;
     7     node *p1,*p2;
     8     p1=head;
     9     p2=head;
    10     while(m){//这样p1和p2相差M个单位长度,当p2走到尽头的时候,p1指向的元素就是倒数第m个元素
    11         if(p2->next!=NULL){
    12              p2=p2->next;
    13              m--;
    14         }
    15         else
    16              return NULL;
    17     }
    18     while(p2->next!=NULL){
    19         p1=p1->next;
    20         p2=p2->next;
    21     }
    22     return p1;
    23 }
    View Code
  • 相关阅读:
    jQuery(2)
    jQuery(1)
    underscore.js
    面向对象复习
    1.14函数复习
    面向对象(3)继承
    10.18
    1017
    js笔记二
    js笔记一
  • 原文地址:https://www.cnblogs.com/Kobe10/p/5566326.html
Copyright © 2011-2022 走看看