• [数据结构与算法]小甲鱼教程题目_找出未知长度单链表的中间元素


    据说是腾讯招聘的题目。。

    老实说,我对小甲鱼给出的答案很不以为然,小甲鱼的方法只是循环次数减少了,不见得总的执行次数会少多少。。不知道是不是我对算法的执行效率有误解。。。。。不过我也没有找到更好的办法,贴代码吧。

    我的设想:

      n = GetLength_L();  //获得长度  循环N次

      找到第[n/2]元素  // 循环 [N/2]

    小甲鱼的解法:

      快慢指针方法

      LNode * search ;

          LNode  *mid;

    开始时 search = mid  都指向头指针,然后search每次按两个元素往单链表的后续元素推进,mid每次俺一个元素往单链表的元素推进。当search到达末尾的时候,mid刚好指向中间元素。。。

    就好比两个人一起赛跑(跑道长度位置),甲乙两人同时在起点出发,甲的速度是乙的速度的两倍,甲到终点的时候,乙恰好在中间位置。。。。

    --code为小甲鱼解法的实现。。

     1 /*******************************************************
     2 * @: Project:    找未知长度单链表的中间元素
     3 * @: File:        link_list.h
     4 * @: Function: 提供单链表操作的数据结构定义及方法声明
     5 * @: History:    2013-10-01 22:37:05
     6 * @: Author:    Alimy
     7 *******************************************************/
     8 
     9 /*******************************************************
    10 * @:头文件包含
    11 *******************************************************/
    12 
    13 
    14 #ifndef __LINK_LIST_H__
    15 #define __LINK_LIST_H__
    16 
    17 
    18 /*******************************************
    19 * @: 数据结构定义&一些宏
    20 ********************************************/
    21 #define ElemType   signed short    int            // 此例子中的数据为有符号短整形,在VC6 中占据16bits
    22 #define StatusType    int        //操作状态为int类型
    23 #define OK    (StatusType)1
    24 #define ERROR (StatusType)0
    25 
    26 
    27 typedef struct LNode{
    28     ElemType m_data;              // 数据域
    29     struct LNode *p_next;     // 指针域
    30 } LNode, *pLinkList;
    31 
    32 //typedef struct LHead{ //头结点,其实和 LNode的内存结构相似,
    33 //    int ElemNumber;  //数据域,可以存储当前线性表的长度,也可以什么也不存储
    34 //    struct LNode *p_FirstNode; //指针域指向线性表的第一个元素
    35 //}LHead, *pLHead;
    36 
    37 /*******************************************
    38 * @: 外部调用函数声明
    39 ********************************************/
    40 extern StatusType CreateList_L(pLinkList *pL,int num);//构造num个结点的单链表
    41 extern StatusType GetMidNode(pLinkList *pL,ElemType *pe); //找到未知长度链表的 中间元素
    42 extern void ClearList_L(pLinkList *pL);    //整表删除
    43 extern void DisplayList_L(pLinkList *pL);//输出显示pL指向的链表中的所有元素
    44 
    45 #endif
    link_list.h
      1 /*******************************************************
      2 * @: Project:    找未知长度单链表的中间元素
      3 * @: File:        GetMidNode.c
      4 * @: Function:提供单链表操作相关函数
      5 * @: Version:    2013-10-09 22:09:36
      6 * @: Author:    Alimy
      7 *******************************************************/
      8 
      9 /*******************************************************
     10 * @: 头文件包含 
     11 *******************************************************/
     12 
     13 #include "link_list.h"
     14 #include <stdio.h> 
     15 #include <conio.h>        // int getch(void);
     16 #include <stdlib.h>        // int rand(void);  malloc(); free();
     17 #include <time.h>            // time_t time(time_t *);
     18 
     19 
     20 /*******************************************************
     21 * @: (外部&内部)变量声明及定义
     22 *******************************************************/
     23 
     24 /*******************************************************
     25 * @: (外部&内部)函数声明及定义
     26 *******************************************************/
     27 StatusType CreateList_L(pLinkList *pL,int num);//构造num个结点的单链表
     28 StatusType GetMidNode(pLinkList *pL,ElemType *pe); //找到未知长度链表的 中间元素
     29 void DisplayList_L(pLinkList *pL);//输出显示pL指向的链表中的所有元素
     30 void ClearList_L(pLinkList *pL);    //整表删除
     31 
     32 
     33 
     34 /*******************************************************
     35 * @: 内部函数具体实现
     36 *******************************************************/
     37 
     38 
     39 /*
     40 *@:在堆中构造一个单链表,并逆序插入num个结点(头插法)
     41 *@:返回值 
     42 *@:    构造成功返回OK
     43 *@: 构造失败返回ERROR
     44 **/
     45 StatusType CreateList_L(pLinkList *pL,int num){//构造num个结点的单链表
     46 
     47     LNode*  p_Work = NULL; //工作指针
     48     int idx = 0;
     49     
     50     if(*pL!=NULL){
     51         printf("当前单链表已被初始化,不需要执行Create操作 
    ");
     52         return ERROR;
     53     }
     54 
     55     *pL = (pLinkList)malloc(sizeof(LNode));
     56     if(*pL == NULL){
     57         printf("在堆中申请头结点失败 
    ");
     58         return ERROR;        
     59     }
     60     (*pL)->m_data = 0;  // 数据域可以存储当前单链表的长度
     61     (*pL)->p_next = NULL;
     62     
     63     srand(time(0));
     64     for(idx=0;idx<num;idx++){
     65         p_Work = (pLinkList)malloc(sizeof(LNode)); //在堆中申请新的结点
     66         if(p_Work==NULL){
     67             printf("在堆中申请结点出现异常,构造单链表失败  
    ");
     68             return ERROR;
     69         }
     70         
     71         //p_Work->m_data = 10*s_data[idx%10];//(rand()%(10)); //均为10以内的整数
     72         p_Work->m_data = (rand()%(100))+1; //晕死,每次生产的随机数怎么都一样
     73         p_Work->p_next = (*pL)->p_next;
     74         (*pL)->p_next = p_Work;          //逆序插入,第一个产生为表尾
     75     }
     76     printf("构造含【%d】个元素的单链表成功
    ",num);
     77     getch();
     78     return OK;
     79 }
     80 /*
     81 *@:在pL指向的未知长度的单链表中找到中间元素,并将中间元素的值赋值给pe指向的内存
     82 *@:返回值
     83 *     找到         -->    返回OK
     84 *            没找到    -->    返回ERROR
     85 */
     86 
     87 StatusType GetMidNode(pLinkList *pL,ElemType *pe){ //找到未知长度链表的 中间元素
     88     LNode * p_search = NULL; //快指针
     89     LNode * p_mid = NULL;        //慢指针
     90     
     91     p_search = p_mid = *pL; // 都指向头结点
     92     
     93     if((*pL)->p_next == NULL){
     94         printf("此单链表为空表,无法执行找到中间元素的操作 
    ");
     95         return ERROR;
     96     }
     97     if(p_search->p_next->p_next == NULL){
     98         printf("此单链表的元素个数为1
    ");
     99         *pe = p_search->p_next->m_data;
    100         return OK;
    101         }
    102     
    103     while(p_search->p_next!=NULL){
    104         if(p_search->p_next->p_next!=NULL){
    105             p_mid = p_mid ->p_next;
    106             p_search = p_search->p_next->p_next;
    107             }    
    108             else{
    109                 p_search = p_search->p_next;//让while跳出循环
    110                 }
    111     }
    112 
    113     *pe = p_mid->m_data;
    114     return OK;
    115 
    116 }
    117 
    118 
    119 /*
    120 *@: 输出显示pL指向的单链表所有的元素
    121 */
    122 void DisplayList_L(pLinkList *pL){ //显示当前所有单链表的长度
    123 
    124     int idx = 0;
    125     LNode* p_Work = NULL;
    126 
    127     if(*pL==NULL){
    128         printf("单链表还未构建,输不出东东 
    ");
    129         return ;
    130     }
    131     
    132     idx = 0;
    133     p_Work = (*pL); // 工作指针指向头结点,计数清零
    134     if(p_Work->p_next==NULL){
    135         printf("当前单链表为空表,没什么东东好显示的 
    ");
    136         return ;
    137     }
    138     else{
    139         while(p_Work->p_next){ //(p_Work->p_next!=NULL)
    140             idx++;
    141             p_Work = p_Work->p_next;
    142             printf("单链表第【%d】个元素的值为【%d】
    ",idx,p_Work->m_data);
    143         }
    144         return ;
    145     }
    146     
    147     
    148 }
    149 
    150 
    151 /*
    152 *@:删除pL指向的单链表的所有结点
    153 */
    154 
    155 void ClearList_L(pLinkList *pL){    //整表删除
    156     LNode* p_Work1 = NULL;
    157     LNode* p_Work2 = NULL; //工作指针
    158     
    159     if(*pL == NULL){
    160         printf("当前单链表未创建,无法执行整表删除操作 
    ");
    161         return ;
    162     }
    163     else if((*pL)->p_next == NULL){
    164         printf("当前单链表为空表,不需要执行整表删除操作 
    ");
    165         return;
    166     }
    167     else{
    168         p_Work1 = (*pL)->p_next; // 指向第一个结点(如果有的话)
    169         while(p_Work1!=NULL){
    170             p_Work2 = p_Work1;
    171             p_Work1 = p_Work2->p_next;//指向下一个
    172             free(p_Work2);
    173         }
    174 
    175     //    (*pL)->p_next = NULL;        // 头结点指向NULL
    176         (*pL)->m_data = 0;
    177         return ;
    178     }
    179 }
    GetMidNode.c
     1 #include <stdio.h>
     2 #include "link_list.h"
     3 
     4 
     5 
     6 int main(void){
     7     int num = 0;
     8     ElemType e = 0;
     9     pLinkList LinkList_Display = NULL;    
    10     printf("请输入你要构建单链表的个数 
    ");
    11     scanf("%d",&num);
    12     CreateList_L(&LinkList_Display,num);
    13     DisplayList_L(&LinkList_Display);
    14     
    15     if(OK == GetMidNode(&LinkList_Display,&e)){
    16         printf("中间元素的值为 【%d】
    ",e);
    17         }
    18         
    19     getch();
    20     
    21     
    22     
    23     // 打扫堆战场
    24     ClearList_L(&LinkList_Display);
    25     if(LinkList_Display != NULL)
    26         free(LinkList_Display);
    27     return OK;
    28     
    29 }
    main.c

      

    ~不再更新,都不让我写公式,博客园太拉胯了
  • 相关阅读:
    HDU 1874 畅通工程续(dijkstra)
    HDU 2112 HDU Today (map函数,dijkstra最短路径)
    HDU 2680 Choose the best route(dijkstra)
    HDU 2066 一个人的旅行(最短路径,dijkstra)
    关于测评机,编译器,我有些话想说
    测评机的优化问题 时间控制
    CF Round410 D. Mike and distribution
    数字三角形2 (取模)
    CF Round410 C. Mike and gcd problem
    CF Round 423 D. High Load 星图(最优最简构建)
  • 原文地址:https://www.cnblogs.com/alimy/p/3362006.html
Copyright © 2020-2023  润新知