重温数据结构的单链表后,发现手写还是很容易出问题(经常写越界之类的…),删删改改还是写完了,具有一定基础功能的单链表
#include <bits/stdc++.h>
using namespace std;
/*
Author XT
Date 2020/9/11 1:00
Title 单链表
*/
//自定义结构
struct List {
int data;
List* next;
};
//初始化链表
void InitList(List*& L)
{
L = (List*)malloc(sizeof(List));
L->next = NULL;
}
//查询链表长度
int GetLength(List* L)
{
int cnt = 0;
List* p = L;
while (p != NULL) {
p = p->next;
cnt++;
}
return cnt - 1; //cnt计数时算入了为不保存数据的head所以需要-1
}
//往链表某位置插入元素
void InsertList(List*& L, int ip, int x)
{
List *p = L, *pre;
int i, len;
len = GetLength(L);
if (ip < 1 || ip > len + 1) { //判断地址是否合法
printf("请正确输入插入地址!\n");
return;
}
for (i = 1; i < ip; i++) //寻找插入点
p = p->next;
pre = (List*)malloc(sizeof(List));
pre->data = x;
pre->next = p->next;
p->next = pre;
}
//删除链表中某位置的元素
void Delete(List*& L, int ip)
{
List *p = L, *pre;
int i, len;
len = GetLength(L);
if (ip < 1 || ip > len) { //判断地址是否合法
printf("请正确输入插入地址!\n");
return;
}
for (i = 1; i < ip; i++) //寻找插入点
p = p->next;
pre = p->next;
p->next = p->next->next;
free(pre);
}
//查询元素的位置
void Findip(List* L, int x)
{
List* p = L;
int cnt = 0;
while (1) {
p = p->next;
cnt++;
if (p == NULL)
break;
if (p->data == x)
break;
}
if (p != NULL) {
printf("该位置元素值为:%d\n", cnt);
return;
}
printf("该元素不在链表中,请重新输入!\n");
return;
}
//查询某位置的元素值
void Find(List* L, int ip)
{
List* p = L;
int i;
if (ip < 1 || ip > GetLength(L)) { //判断地址是否合法
printf("请正确输入插入地址!\n");
return;
}
for (i = 0; i < ip; i++)
p = p->next;
printf("该位置元素值为:%d\n", p->data);
}
//清空链表
void ClearList(List*& L)
{
List *p, *pre;
p = L->next;
while (p) {
pre = p->next;
free(p);
p = pre;
}
L->next = NULL;
}
//输出链表中所有元素
void AllList(List* L)
{
List* p = L->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
//头插法:将数据一个一个插入(尾 <- 头)
void GeateHeadList(List*& L, int a[], int n)
{
List* p;
for (int i = 0; i < n; i++) {
p = (List*)malloc(sizeof(List));
p->data = a[i];
p->next = L->next;
L->next = p;
}
}
//尾插法:将元素一个一个插入(尾 -> 头)
void GeateTailList(List*& L, int a[], int n)
{
List *p, *pre = L;
for (int i = 0; i < n; i++) {
p = (List*)malloc(sizeof(List));
p->data = a[i];
pre->next = p;
pre = p;
}
pre->next = NULL;
}
int main() //仅提供基础模板,可自行修改
{
List* l;
int ip, x;
InitList(l);
printf("当前链表长度为:%d\n", GetLength(l));
printf("请输入元素要插入的位置和元素的值:\n");
while (~scanf("%d %d", &ip, &x))
InsertList(l, ip, x);
printf("当前链表中元素有:\n");
AllList(l);
printf("当前链表长度为:%d\n", GetLength(l));
printf("请输入要删除的元素位置:\n");
while (~scanf("%d", &ip))
Delete(l, ip);
printf("当前链表中元素有:\n");
AllList(l);
printf("当前链表长度为:%d\n", GetLength(l));
printf("请输入要查询的位置:\n");
while (~scanf("%d", &ip))
Find(l, ip);
printf("请输入要查询的元素:\n");
while (~scanf("%d", &x))
Findip(l, x);
ClearList(l); //申请的空间应该重新释放
//随机数生成
int a[10], left, right;
printf("请输入随机数范围:\n");
scanf("%d %d", &left, &right);
memset(a, 0, sizeof(a));
for (int i = 0; i < 10; i++)
a[i] = left + rand() % (right - left + 1);
printf("随机数为:\n");
for (int i = 0; i < 10; i++)
printf("%5d", a[i]);
printf("\n");
InitList(l);
printf("当前链表中元素为(头插法):\n");
GeateHeadList(l, a, 10);
AllList(l); //输出表中全部元素
ClearList(l); //释放内存
InitList(l);
printf("当前链表中元素为(尾插法):\n");
GeateTailList(l, a, 10);
AllList(l);
ClearList(l);
return 0;
}