zoukankan      html  css  js  c++  java
  • 链表操作二——中间结点的删除等

    一:特殊要求的结点删除

    问题描述:假设有一个没有头指针的单链表。一个指针指向此单链表中间的一个结点(不是第一个,也不是最后一个)。请将该节点从单链表中删除。

    思路:根据题意,似乎很难完成。其实我们可以将当前结点的后续结点的值域赋值给当前结点的值域。然后再删除当前结点的后续结点,即可完成”狸猫换太子“。代码如下:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <time.h>
     5 
     6 typedef struct tag
     7 {
     8     int Nnum_;
     9     struct tag *Nnext_;
    10 }Node, *pNode;
    11 
    12 
    13 void link_print(pNode phead)
    14 {
    15     while(phead != NULL)
    16     {
    17         printf("%4d", phead->Nnum_);
    18         phead = phead->Nnext_;
    19     }
    20     printf("
    ");
    21 }
    22 //头插法
    23 void link_init_tail(pNode *phead, int size) //传的是地址
    24 {
    25     pNode pNew = NULL;
    26     pNode pTail = NULL;
    27 
    28     while( size > 0)
    29     {
    30         //申请内存
    31         pNew = (pNode)malloc(sizeof(Node)); //注意这里为何不用pNode而用Node,因为sizeof(pNode) = 4
    32         //赋值
    33         pNew->Nnum_ = rand()%1000;
    34         //插入链表
    35         if(*phead == NULL) //链表为空时
    36         {
    37             *phead = pNew;//连接新的结点
    38             pTail = pNew;
    39         }
    40         else//不为空
    41         {
    42             pTail->Nnext_ = pNew ; //连接新的结点
    43              pTail = pNew; //改名字
    44         }        
    45         size --;
    46     }
    47 }
    48 
    49 int delete_special_pos(pNode *phead) //为了验证结果而将其打印出来,我们采用带有头指针的链表
    50 {
    51     if(*phead == NULL && (*phead)->Nnext_ == NULL)
    52         return 0;
    53     int i = 1;//为了叙述方便,我们假设其位置是3
    54 
    55     pNode pCur = *phead;
    56     while( i < 3) //使pCur指向第三个结点
    57     {
    58         pCur = pCur->Nnext_;
    59         i ++;
    60     }
    61     //删除第三个结点的int值
    62     pNode pNext = pCur->Nnext_; //建立初始值
    63     //我们要把pNext所指向结点int值放到pCur中,然后再删除pNext。此刻就完成了“狸猫换太子”
    64     pCur->Nnext_ = pNext->Nnext_; 
    65     pCur->Nnum_ = pNext->Nnum_;
    66     free(pNext);
    67     pNext = NULL; //防止野指针的出现
    68     return 1;
    69 }    
    70 
    71 int main(int argc, char const *argv[])
    72 {
    73     srand(time(NULL));
    74     pNode phead = NULL;
    75     link_init_tail(&phead, 10);
    76     link_print(phead);    
    77 
    78     printf("ret:%d
    ",delete_special_pos(&phead) );
    79     link_print(phead);
    80 
    81     return 0;
    82 }
    View Code

    二:编码实现环状单向链表(尾指针直接指向头指针,中间没有空结点),去除连续的重复元素的操作。(2012,人人)

    比如:1(头)->2 ->2 ->3 ->3 ->1 ->1(头),去除以后的结果是 1 ->2 ->3(注意头部的 1 也要去掉一个); 

    思路:

    1、如果该链表为空或者长度为1,则直接返回。
    2、遍历一次循环单向链表,删除连续的重复的结点;
    3、判断最后一个结点是否和第一个结点值相同:
    一)若相同,删除最后一个结点,并且返回头结点;
    二)若不相同,直接返回头结点。

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <time.h>
      5 #include <assert.h>
      6 
      7 typedef struct tag
      8 {
      9     int Nnum_;
     10     struct tag *Nnext_;
     11 }Node, *pNode;
     12 
     13 
     14 void link_print(pNode phead, int size)
     15 {
     16     int i= 1;
     17     while(phead != NULL)
     18     {
     19         printf("%2d", phead->Nnum_);
     20         phead = phead->Nnext_;
     21         if( ++i > size)
     22             break;
     23     }
     24     printf("
    ");
     25 }
     26 //尾插法
     27 void link_init_tail(pNode *phead, int size) //传的是地址
     28 {
     29     pNode pNew = NULL;
     30     pNode pTail = NULL;
     31 
     32     while( size > 0)
     33     {
     34         //申请内存
     35         pNew = (pNode)malloc(sizeof(Node)); //注意这里为何不用pNode而用Node,因为sizeof(pNode) = 4
     36         //赋值
     37         //pNew->Nnum_ = rand()%5;
     38         pNew->Nnum_ = 1; 
     39 
     40         //插入链表
     41         if(*phead == NULL) //链表为空时
     42         {
     43             *phead = pNew;//连接新的结点
     44             pTail = pNew;
     45         }
     46         else//不为空
     47         {
     48             pTail->Nnext_ = pNew ; //连接新的结点
     49              pTail = pNew; //改名字
     50         }    
     51         size --;
     52     }
     53     //生成一个首尾相连的环
     54     pTail->Nnext_ = *phead;
     55 }
     56 
     57 pNode unique( pNode phead)
     58 {
     59     //如果该链表为空或者长度为1,则直接返回。
     60     if( phead == NULL || phead->Nnext_ ==NULL)
     61         return phead;
     62 
     63     //遍历一次循环单向链表,
     64     pNode pCur = phead;
     65     pNode pNext = pCur->Nnext_;
     66 
     67     while(pNext != phead) 
     68     {
     69         //删除连续的重复的结点
     70         while(pCur->Nnum_ == pNext->Nnum_ && pNext != phead) 
     71         {
     72             pCur->Nnext_ = pNext->Nnext_;
     73             free(pNext);
     74             pNext= pCur->Nnext_;
     75         }
     76 
     77         if( pNext == phead) //判断最后一个结点是否和第一个结点值相同
     78             break;
     79         //int值不相等-->向后移动
     80         pCur = pNext;
     81         pNext = pNext->Nnext_;
     82     }
     83     
     84     if( pCur->Nnum_ == pNext->Nnum_)
     85     {
     86     //所有值域全部相同
     87         if(pNext == pCur) 
     88         {
     89             printf("All the link's elements are equal
    ");
     90             printf("the value is:%d
    ",pNext->Nnum_);
     91             //free(pNext);// 为什么加上这两句就错了?
     92             //pNext = NULL;
     93             return pCur;
     94         }
     95     //存在值域不相同的结点->此时剩余的结点组成一个循环链表
     96         pCur->Nnext_ = pNext->Nnext_;
     97         free(pNext);
     98         return pCur;
     99     }
    100     //不相等,这时pNext == *phead
    101     return pNext;
    102 }
    103 
    104 int main(int argc, char const *argv[])
    105 {
    106     srand(time(NULL));
    107     pNode phead = NULL;
    108     link_init_tail(&phead, 10); //10为初始链表的长度
    109     link_print(phead,15); 
    110 
    111     pNode pRet = unique(phead);
    112 
    113     link_print(pRet, 10);
    114     return 0;
    115 }
    View Code

    链表的快慢指针的使用,详见下篇:链表三——快慢指针的使用

  • 相关阅读:
    用户登录就显示一部分按钮,未登录就显示登录按钮
    网页防止xss攻击
    前端页面使用编辑器
    Django框架
    参数*args与**kwargs
    Django的orm需要注意的地方
    查看Linux服务器配置命令
    PHP 浅析spl_autoload_register
    ubuntu服务器上安装PHP扩展bcmath遇到的问题Sub-process /usr/bin/dpkg returned an error code (1)
    JavaScript 变量and函数提升机制
  • 原文地址:https://www.cnblogs.com/xfxu/p/4088239.html
Copyright © 2011-2022 走看看