数据结构(一)线性表单链表试题

题目

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

解决思路

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

算法复杂度: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("----------------------\n");
    printf("0.Exit\n");
    printf("1.InitList\n");
    printf("2.CreateListByHead\n");
    printf("3.CreateListByEnd\n");
    printf("4.ShowList\n");
    printf("5.findMidElem\n");
    printf("6.clear list\n");
    printf("7.clear screen\n");
    printf("----------------------\n");
}

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\n");
                continue;
            }
            if (n == 1)
                if (InitList(&L))
                    printf("InitList successful\n");
                else
                    printf("InitList failure\n");
            else if (n == 2)
            {
                printf("please choose the number to create list:");
                scanf("%d", &n);
                if (CreateListHead(&L, n))
                    printf("CreateListHead successful\n");
                else
                    printf("CreateListHead failure\n");
            }
            else if (n == 3)
            {
                printf("please choose the number to create list:");
                scanf("%d", &n);
                if (CreateListEnd(&L, n))
                    printf("CreateListEnd successful\n");
                else
                    printf("CreateListEnd failure\n");
            }
            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\n", e, index);
                else
                    printf("find failure! you must inital list and create element first\n");
            }
            else if (n == 6)
                if (ClearList(&L))
                    printf("ClearList success\n");
                else
                    printf("ClearList failure\n");
        }
    }
    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("\n");
}

//快速查找中间元素
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;
}

效果预览

原文地址:https://www.cnblogs.com/ssyfj/p/9420728.html

时间: 2024-10-28 17:41:53

数据结构(一)线性表单链表试题的相关文章

数据结构之 线性表---单链表操作A (删除链表中的指定元素)

数据结构上机测试2-1:单链表操作A Time Limit: 1000MS Memory limit: 4096K 题目描述 输入n个整数,先按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据m,将单链表中的值为m的结点全部删除.分别输出建立的初始单链表和完成删除后的单链表. 输入 第一行输入数据个数n: 第二行依次输入n个整数: 第三行输入欲删除数据m. 输出 第一行输出原始单链表的长度: 第二行依次输出原始单链表的数据: 第三行输出完成删除后的单链表长度: 第四行依次输出完成删除后的

数据结构之 线性表---单链表的操作B(先逆序+再删除重复元素)

数据结构上机测试2-2:单链表操作B Time Limit: 1000MS Memory limit: 65536K 题目描述 按照数据输入的相反顺序(逆位序)建立一个单链表,并将单链表中重复的元素删除(值相同的元素只保留最后输入的一个). 输入 第一行输入元素个数n: 第二行输入n个整数. 输出 第一行输出初始链表元素个数: 第二行输出按照逆位序所建立的初始链表: 第三行输出删除重复元素后的单链表元素个数: 第四行输出删除重复元素后的单链表. 示例输入 10 21 30 14 55 32 63

数据结构之 线性表---单链表的拆分

数据结构实验之链表五:单链表的拆分 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数.两个子链表中数据的相对次序与原链表一致. 输入 第一行输入整数N;: 第二行依次输入N个整数. 输出 第一行分别输出偶数链表与奇数链表的元素个数: 第二行依次输出偶数子链表的所有数据: 第三行依次输出奇数子链表的所有数据. 示例输入 10 1 3 22

数据结构之 线性表---单链表的应用(重复元素删除)

数据结构上机测试1:顺序表的应用 Time Limit: 1000MS Memory limit: 65536K 题目描述 在长度为n(n<1000)的顺序表中可能存在着一些值相同的“多余”数据元素(类型为整型),编写一个程序将“多余”的数据元素从顺序表中删除,使该表由一个“非纯表”(值相同的元素在表中可能有多个)变成一个“纯表”(值相同的元素在表中只能有一个). 输入 第一行输入表的长度n: 第二行依次输入顺序表初始存放的n个元素值. 输出 第一行输出完成多余元素删除以后顺序表的元素个数: 第

【 数据结构(C语言)】线性表——单链表

1.线性链表:用任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的也可以是不连续) #include <bits/stdc++.h> using namespace std; #define ElemType int #define Status int #define ERROR -1 #define OK 1 typedef struct LNode { ElemType data; struct LNode *next; }LNode ,*LinkList; LinkList

数据结构 线性表—单链表

本文只要实现单链表的初始化.插入(尾插.头插.任意位置插入).删除(尾删.头删.删除指定元素).查找等. 定义单链表 typedef int DataType; typedef struct LinkNode {  DataType data;  struct LinkNode *next; }LinkNode, *pLinkNode, *pList; 实现单链表的所有接口: void InitLinkList(pList* pHead);//单链表的初始化 void Destroy(pList

JAVA实现具有迭代器的线性表(单链表)

一,迭代器的基本知识: 1,为什么要用迭代器?(迭代:即对每一个元素进行一次“问候”) 比如说,我们定义了一个ADT(抽象数据类型),作为ADT的一种实现,如单链表.而单链表的基本操作中,大部分需要用到依次遍历单链表中的每一个元素.一般而言,我们就是用for循环来实现遍历,这样,当你新增一个对单链表的操作并需要使用遍历时,你就得重新写一个for循环而实现遍历.那么,为什么不将迭代(遍历)作为一种基本的ADT操作(基本的ADT操作如:新增一个元素.删除一个元素)呢?于是,迭代器就出场了. 2,鉴于

数据结构之线性表(链表)

链表 1.链表的定义:线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是 连续的,也可以是不连续的).因此,为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素 ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置).这两部分信息组 成数据元素ai的存储映像,称为结点.它包括两个域,其中存储数据元素信息的域称为数据域:存储直接后继存储位置的 域称为指针域.指针域中存储的信息称做指针或链.n个结点

Python线性表——单链表

1. 线性表简介 线性表是一种线性结构,它是由零个或多个数据元素构成的有限序列.线性表的特征是在一个序列中,除了头尾元素,每个元素都有且只有一个直接前驱,有且只有一个直接后继,而序列头元素没有直接前驱,序列尾元素没有直接后继. 数据结构中常见的线性结构有数组.单链表.双链表.循环链表等.线性表中的元素为某种相同的抽象数据类型.可以是C语言的内置类型或结构体,也可以是C++自定义类型. 2. 数组 数组在实际的物理内存上也是连续存储的,数组有上界和下界.C语言中定义一个数组: 数组下标是从0开始的