题目
解决思路
(一)使用一个指针,先索引一遍获取总长度,再取长度一半去循环获取到中间值
算法复杂度:O(L)+O(L/2) = O(3L/2)
(二)使用两个指针,快指针和慢指针,快指针一次向前走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;
}
效果预览