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

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

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

    我的设想:

      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

      

    ~不再更新,都不让我写公式,博客园太拉胯了
  • 相关阅读:
    TCP带外数据
    ASP.Net Core 返回的json数据,自定义日期格式
    C# 简单的区块链实现
    PowerShell自动部署ASP.NET Core程序到 IIS
    ASP.NET Core依赖注入多个服务实现类
    EF Core 2.0 执行原始查询如何防止SQL注入
    C#7 进入快速迭代道路
    QuartzNet 任务管理系统
    WebApi如何传递参数
    C# 快速高效率复制对象另一种方式 表达式树
  • 原文地址:https://www.cnblogs.com/alimy/p/3362006.html
Copyright © 2011-2022 走看看