手写简单单链表(多插入法)

重温数据结构的单链表后,发现手写还是很容易出问题(经常写越界之类的…),删删改改还是写完了,具有一定基础功能的单链表

#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;
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值