zoukankan      html  css  js  c++  java
  • 数据结构(一)线性表单链表试题

    题目

    快速找到未知长度的单链表的中间节点

    解决思路

    (一)使用一个指针,先索引一遍获取总长度,再取长度一半去循环获取到中间值

    算法复杂度:O(L)+O(L/2) = O(3L/2)

     (二)使用两个指针,快指针和慢指针,快指针一次向前走2格,慢指针一次走一格,当快指针走完全程,慢指针正好走在中间

    算法复杂度:O(L/2)

    方法二:代码实现

    //快速查找中间元素
    int FindMidEle(LinkList L, Elemtype *e)
    {
        LinkList search, middle;    //search是快指针,middle是慢指针
        int i=0;
    
        if (L == NULL || e == NULL)
            return i;
    
        search = middle = L;
        while (search->next)
        {
            if (search->next->next!=NULL)    //快指针是慢指针的两倍速度
            {
                search = search->next->next;
                middle = middle->next;
            }
            else       //是针对奇数个元素,再次进行操作,是之能够退出
            {
                search = search->next;
                middle = middle->next;  //奇数需要再次向后取一位,才会到达中间
            }
            i++;
        }
        *e = middle->data;
        return i;
    }

    全部代码实现

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    
    #define ERROR 0 
    #define OK 1
    #define FALSE 0
    #define TRUE 1
    
    typedef int Status;
    typedef int Elemtype;
    
    typedef struct Node
    {
        Elemtype data;
        struct Node* next;
    }Node;
    
    typedef struct Node* LinkList;
    
    //初始化链表
    Status InitList(LinkList* L);
    //创建元素
    Elemtype CreateElem(int n);
    //尾插法创建链表
    Status CreateListEnd(LinkList* L, int n);
    //头插法创建链表
    Status CreateListHead(LinkList* L, int n);
    //清空链表
    Status ClearList(LinkList* L);
    //判断链表是否为空
    Status ListEmpty(LinkList L);
    //打印链表
    void PrintList(LinkList L);
    //快速查找中间元素
    int FindMidEle(LinkList L, Elemtype *e);
    
    void ShowMenu()
    {
        system("cls");
        printf("----------------------
    ");
        printf("0.Exit
    ");
        printf("1.InitList
    ");
        printf("2.CreateListByHead
    ");
        printf("3.CreateListByEnd
    ");
        printf("4.ShowList
    ");
        printf("5.findMidElem
    ");
        printf("6.clear list
    ");
        printf("7.clear screen
    ");
        printf("----------------------
    ");
    }
    
    int main()
    {
        LinkList L=NULL;
        int n;
        Elemtype e;
        srand(time(0));    //生成随机数种子
    
        while (1)
        {
            ShowMenu();
            while (1)
            {
                scanf("%d", &n);
                if (n == 0)
                    return 0;
                if (n == 7)
                    break;
                if (n != 1 && L == NULL)
                {
                    printf("you must intilist first
    ");
                    continue;
                }
                if (n == 1)
                    if (InitList(&L))
                        printf("InitList successful
    ");
                    else
                        printf("InitList failure
    ");
                else if (n == 2)
                {
                    printf("please choose the number to create list:");
                    scanf("%d", &n);
                    if (CreateListHead(&L, n))
                        printf("CreateListHead successful
    ");
                    else
                        printf("CreateListHead failure
    ");
                }
                else if (n == 3)
                {
                    printf("please choose the number to create list:");
                    scanf("%d", &n);
                    if (CreateListEnd(&L, n))
                        printf("CreateListEnd successful
    ");
                    else
                        printf("CreateListEnd failure
    ");
                }
                else if (n == 4)
                    PrintList(L);
                else if (n == 5)
                {
                    int index = FindMidEle(L, &e);
                    if (index != 0)
                        printf("find middle element:%d in:%d
    ", e, index);
                    else
                        printf("find failure! you must inital list and create element first
    ");
                }
                else if (n == 6)
                    if (ClearList(&L))
                        printf("ClearList success
    ");
                    else
                        printf("ClearList failure
    ");
            }
        }
        system("pause");
        return 0;
    }
    
    //初始化链表
    Status InitList(LinkList* L)
    {
        if (*L == NULL)
        {
            *L = (LinkList)malloc(sizeof(Node));
            if (*L == NULL)
                return ERROR;
            (*L)->next = NULL;
        }
        else
            if (!ListEmpty(*L))
                ClearList(L);
        return OK;
    }
    
    Elemtype CreateElem(int n)
    {
        return rand() % (n*n);
    }
    
    //尾插法创建链表,创建n个随机元素
    Status CreateListEnd(LinkList* L, int n)
    {
        LinkList q, p;
        q = *L;
    
        if ((*L) == NULL || n < 1)
            return ERROR;
    
        if (!ListEmpty(*L))
            ClearList(L);
    
        for (int i = 0; i < n;i++)
        {
            p = (LinkList)malloc(sizeof(Node));
            p->data = CreateElem(n);
            q->next = p;
            q = p;
        }
        q->next = NULL;
    
        return OK;
    }
    
    //头插法创建链表
    Status CreateListHead(LinkList* L, int n)
    {
        LinkList q, p;
        q = *L;
    
        if ((*L) == NULL || n < 1)
            return ERROR;
    
        if (!ListEmpty(*L))
            ClearList(L);
    
        for (int i = 0; i < n; i++)
        {
            p = (LinkList)malloc(sizeof(Node));
            p->data = CreateElem(n);
            p->next = q->next;
            q->next = p;
        }
    
        return OK;
    }
    
    //清空链表(不会清除头结点)
    Status ClearList(LinkList* L)
    {
        LinkList q, p;
        q = (*L)->next;    //是q指向第一个结点
        while (q)
        {
            p = q;
            q = q->next;
            free(p);
        }
        (*L)->next = NULL;
        return OK;
    }
    
    //判断链表是否为空
    Status ListEmpty(LinkList L)
    {
        if (L->next)
            return FALSE;
        return TRUE;
    }
    
    //打印链表
    void PrintList(LinkList L)
    {
        LinkList q = L;
        while (q=q->next)
            printf("%d ", q->data);
        printf("
    ");
    }
    
    //快速查找中间元素
    int FindMidEle(LinkList L, Elemtype *e)
    {
        LinkList search, middle;    //search是快指针,middle是慢指针
        int i=0;
    
        if (L == NULL || e == NULL)
            return i;
    
        search = middle = L;
        while (search->next)
        {
            if (search->next->next!=NULL)    //快指针是慢指针的两倍速度
            {
                search = search->next->next;
                middle = middle->next;
            }
            else       //是针对奇数个元素,再次进行操作,是之能够退出
            {
                search = search->next;
                middle = middle->next;
            }
            i++;
        }
        *e = middle->data;
        return i;
    }

    效果预览

  • 相关阅读:
    java设计模式演示样例
    一步一步写算法(之排序二叉树)
    收集经常使用的.net开源项目
    jdbc连接数据库
    Android开发系列(二十二):AdapterViewFlipper的功能和使用方法
    ProgressDialog使用总结
    HDU 4916 树分治
    [Unity3D]自制UnityForAndroid二维码扫描插件
    IOS ARC和非ARC文件混用
    让子弹飞Demo版
  • 原文地址:https://www.cnblogs.com/ssyfj/p/9420728.html
Copyright © 2011-2022 走看看