栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

1.4带头结点实现单链表相关操作

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

1.4带头结点实现单链表相关操作

关于带头结点的单链表的相关功能的函数已经实现不足之处代码中也已提示日后会修改,因为这只是第一遍,希望大佬发现错误给予指出QAQ.

//以下代码是带头结点的相关操作,且我的代码现在不够健壮,有一些非法操做
//如数组越界或值非法等目前没给出判断,因为第一遍想先实现函数的基本功能后续待完善
#include 

using namespace std;
typedef struct LNode {
    int data;//存储数据
    struct LNode *next;//存储下一个结点的地址,故用指针类型
} LNode, *LinkList;//这里是将定义和改名一起实现的,通过typedef来进行重命名
// 将struct LNode变为LNode,struct LNode *变为LinkList.其实这里我有个疑问struct已经定义了一个LNode结构体类型了.
// 那么我应该可以直接用LNode随便定义了鸭,为什么还要在前面加struct,例如struct LNode *next我可以直接写成LNode *next鸭
//于是乎查了一下发现c++中可以这样写(可以省略struct),但c语言中就是要加struct,c++如下是可以的,但c语言中这样就是错的.

//下面正文开始了
//头插法建立单链表
LinkList List_HeaderInsert(LinkList &L, int n) {//该函数写的与辅导书上不同
    int x;
    //初始化点链表分配内存
    L = (LNode *) malloc(sizeof(LNode));
    L->next = NULL;//带头节点初始方法
    for (int i = 1; i <= n; i++) {
        cin >> x;
        LNode *s;//建立一个新节点用于储存数据,以后是表的一部分
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;//
        s->next = L->next;//这三句很重要,顺序不可错
        L->next = s;//
    }
    return L;
}

//尾插法建立单链表
LinkList List_TailInsert(LinkList &L, int n) {
    int x;
    //初始化点链表分配内存
    L = (LNode *) malloc(sizeof(LNode));
    L->next = NULL;//带头节点初始方法
    LinkList p = L;//这里定义一个变量代表尾指针(因为带头结点的后面还有个NULL,所以这个实在NULL前面的尾指针,每次都要插在它后面
    for (int i = 1; i <= n; i++) {
        cin >> x;
        LNode *s;//建立一个新节点用于储存数据,以后是表的一部分
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;//
        s->next = p->next;//这三句别搞错了
        p->next = s;//
        p = s;//别忘了每次更改尾指针
    }
    return L;
}

//按位序插入
void ListInsert(LinkList &L, int i, int e) {//插入到第i位,则需要找到i-1个节点(因为单链表的单向性,他只保存了下一个结点的内存地址)
    LNode *p = L;
    int j = 0;
    //cout<<"'cdv,dss,vsd,v;d,"<//利用循环找到第i个节点
        p = p->next;
        j++;
    }
    //然后将待插入的节点放在i-1个节点的后面,完美散花
    LNode *s = (LNode *) malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    //或者将上述四句写成InsertNextNode函数
}

//给定节点的后插操作,我觉得这个函数是个工具中的工具函数
void InsertNextNode(LNode *p, int e) {
    LNode *s = (LNode *) malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
}

//给定节点的前插操作
void InsertpriorNode(LNode *p, int e) {//这个函数就有意思了,因为没有前指针这咋办呢,我说插不了插不了
    //我一个偷换概念,偷袭,昂,我说你这就不讲武德~~
    //回归正题,既然前面没法插,但他的要求只是数的前后顺序,我把给定节点的data和新节点的data换一下,让新节点但插在给定节点后面
    // 这不也等同于前插了吗,这函数就是个老6嘻嘻
    LNode *s = (LNode *) malloc(sizeof(LNode));
    s->data = p->data;
    p->data = e;
    s->next = p->next;
    p->next = s;
}

//按位序删除
void ListDelete(LinkList &L, int i, int &e) {
    int j = 0;
    LNode *p = L, *s;
    while (j < i - 1) {//我默认存在前面也说了代码不够健壮,所以没判断p是否为空
        p = p->next;
        j++;
    }
    //此时p是i-1位的节点,为什么要找i-1位结点是因为删除操作要用到
    s = p->next;//s是第i位节点
    p->next = s->next;
    e = s->data;
    free(s);
}

//给定节点删除
void DeleteNode(LNode *p, int &e) {//这个函数和上面那个给定插入思想一样
    LNode *s = p->next;
    p->data = s->data;
    p->next = s->next;
    free(s);
}

void PrintList(LinkList L) {
    L = L->next;
    while (L) {
        cout << L->data << endl;
        L = L->next;
    }
}

int main() {
    int n, e;
    cin >> n;
    LinkList L = List_HeaderInsert(L, n);//若想用尾插法就将函数替换为List_TailInsert;
    //LinkList L = List_TailInsert(L, n);//若想用尾插法就将函数替换为List_TailInsert;
    ListInsert(L, 5, 9);
    ListDelete(L, 6, e);
    PrintList(L);//通过输出函数可以验证自己每一步是否正确
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/976379.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号