`
chinrui
  • 浏览: 97591 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

链表的实现

阅读更多
#include <iostream>
#include <stdlib.h>

using namespace std;

typedef struct lNode {
    lNode *lNext;
    int data;
} lNode , *LinkedList;

//函数声明
LinkedList initNode();
void showNodes(LinkedList head);
int getLength(LinkedList);

int main()
{
    //初始化头结点
    LinkedList lHead = initNode();

    int arr[100];
    int length;
    cout << "输入您要建立链表的长度:" << endl;
    cin >> length;
    cout << "输入您建立链表的各个结点值:" << endl;
    for(int i = 0; i < length ; i++) {
        cin >> arr[i];
    }
    //测试尾插法初始化链表
    //void initLinkedListAtLast(LinkedList , int , int[]);
    //initLinkedListAtLast(lHead , length , arr);
    //测试头插法初始化链表
    void initLinkedListAtHead(LinkedList , int , int[]);
    initLinkedListAtHead(lHead , length , arr);

    //插入测试
    /*void insertNode(LinkedList head , LinkedList node , int index);
    int iInsertIndex;
    int iInsertValue;
    cout << "插入前链表中所有元素的值为:" << endl;
    showNodes(lHead);
    cout << "请输入您要插入的元素值 :" << endl;
    cin >> iInsertValue;
    LinkedList lInsert = initNode();
    lInsert->data = iInsertValue;
    lInsert->lNext = NULL;
    cout << "请输入您要插入元素的位置,不小于 1,不大于" << getLength(lHead) + 1 << ":" << endl;
    cin >> iInsertIndex;
    insertNode(lHead , lInsert , iInsertIndex);
    cout << "插入后链表里面的元素值为:" << endl;
    showNodes(lHead);*/

    //测试删除
    /*void deleteNode(LinkedList , int);
    int iDeleteIndex;
    cout << "删除前链表中所有元素的值为:" << endl;
    showNodes(lHead);
    cout << "请输入要删除元素的地址值,不小于 1,不大于 " << getLength(lHead) << ":" << endl;
    cin >> iDeleteIndex;
    deleteNode(lHead , iDeleteIndex);
    cout << "删除后链表里面的元素值为 :" << endl;
    showNodes(lHead);*/

    //测试查找
    /*LinkedList getNode(LinkedList , int);
    int iSearchIndex;
    cout << "当前链表中所有元素结点的值为:" << endl;
    showNodes(lHead);
    cout << "请输入您要查找元素的地址值,不小于 1,不大于 " << getLength(lHead) << ":" << endl;
    cin >> iSearchIndex;
    LinkedList lResult = getNode(lHead , iSearchIndex);
    if(lResult != NULL) {
        cout << "所查找到的元素值为:" << lResult->data << endl;
    }*/

    //测试修改
    /*void changeNodeValue(LinkedList , int , int);
    int iChangeIndex, iChangeValue;
    cout << "修改前链表中所有元素结点的值:" << endl;
    showNodes(lHead);
    cout << "请输入您要修改结点的值:" << endl;
    cin >> iChangeValue;
    cout << "请输入您要修改结点的地址值:" << endl;
    cin >> iChangeIndex;
    changeNodeValue(lHead , iChangeIndex , iChangeValue);
    cout << "修改后链表里面的元素值为:" << endl;
    showNodes(lHead);*/

    //测试链表的合并
    /*LinkedList mergeLinkedList(LinkedList , LinkedList);
    cout << "第一个链表的所有元素值为:" << endl;
    showNodes(lHead);
    LinkedList mergeList = initNode();
    LinkedList lSecond = initNode();
    initLinkedListAtHead(lSecond , 20);
    cout << "第二个链表的所有元素值为:" << endl;
    showNodes(lSecond);
    mergeList = mergeLinkedList(lHead , lSecond);
    cout << "合并后的链表的所有元素值为:" << endl;
    showNodes(mergeList);*/

    //测试链表的逆转
    void reverseLinkedList(LinkedList , LinkedList);
    cout << "逆转前的链表的所有元素值为:" << endl;
    showNodes(lHead);
    //LinkedList lResult2 = initNode();
    //reverseLinkedList(lHead , lResult2);
    void reverseList(LinkedList);
    reverseList(lHead);
    cout << "逆转后的链表的所有元素值为:" << endl;
    //showNodes(lResult2);
    showNodes(lHead);

    //cout << "链表的长度为:" << getLength(lHead) << endl;
    return 0;
}

//初始化结点
LinkedList initNode() {
    //初始化结点,分配适当的内存空间
    LinkedList node = (LinkedList)(malloc(sizeof(lNode)));
    return node;
}

//初始化链表(尾插法)
void initLinkedListAtList(LinkedList lHead , int lSize , int arr[]) {
    LinkedList curr = lHead;
    LinkedList initNode();
    //初始化长度为iSize的链表,取值以步长为1递增
    for(int i = 0; i < lSize ; i ++) {
        LinkedList lInsert = initNode();
        lInsert->data = arr[i];
        lInsert->lNext = NULL;
        curr->lNext = lInsert;
        curr = curr->lNext;
    }
}

//初始化链表(头插法)
void initLinkedListAtHead(LinkedList lHead , int iSize , int arr[]) {
    LinkedList curr = lHead;
    curr->lNext = NULL;
    //声明生成结点的函数
    LinkedList initNode();
    //在当前指针
    for(int i = 0; i < iSize; i++) {
        LinkedList lInsert = initNode();
        lInsert->data = arr[i];
        lInsert->lNext = curr->lNext;
        curr->lNext = lInsert;
    }
}

//获得链表的长度
int getLength(LinkedList lHead) {
    LinkedList curr = lHead;
    int length = 0;
    while(curr->lNext != NULL) {
        length++;
        curr = curr->lNext;
    }
    return length;
}

//展示所有结点
void showNodes(LinkedList head) {
    while(head->lNext != NULL) {
        head = head->lNext;
        cout << head->data << " ";
    }
    if(head->lNext == NULL)
        cout << endl;
}

//插入结点
void insertNode(LinkedList head , LinkedList node , int index) {
    //判断脚标是否越过下界
    if(index <= 0) {
        cout << "插入失败!您要插入的位置不存在!" << endl;
        return;
    }
    //移动指针到插入脚标的前一个结点
    LinkedList curr = head;
    for(int i = 0; i < index - 1; i++) {
        if(curr->lNext != NULL) {
            curr = curr->lNext;
        } else {
            cout << "插入失败!您要插入的位置不存在!" << endl;
            return;
        }
    }
    //插入结点
    node->lNext = curr->lNext;
    curr->lNext = node;
}

//删除结点
void deleteNode(LinkedList head , int index) {
    //判断脚标是否越过下界
    if(index <= 0) {
        cout << "删除失败!您要删除的结点不存在!" << endl;
        return;
    }
    //移动结点到要删除元素的前一位
    LinkedList curr = head;
    for(int i = 0; i < index - 1; i ++) {
        if(curr->lNext != NULL) {
            curr = curr->lNext;
        } else {
            cout << "删除失败!您要删除的结点不存在!" << endl;
            return;
        }
    }
    if(curr->lNext == NULL) {
        cout << "删除失败!您要删除的结点不存在!" << endl;
        return;
    }
    //删除元素并释放空间
    LinkedList dNode = curr->lNext;
    curr->lNext = dNode->lNext;
    free(dNode);
}

//查找元素
LinkedList getNode(LinkedList head , int index) {
     //判断脚标是否越过下界
    if(index <= 0) {
        cout << "您要查找的结点不存在!" << endl;
        return NULL;
    }
    LinkedList curr = head;
    for(int i = 0; i < index ; i++) {
        if(curr->lNext != NULL) {
            curr = curr->lNext;
        } else {
            cout << "您要查找的结点不存在!" << endl;
            return NULL;
        }
    }
    return curr;
}

//修改结点值
void changeNodeValue(LinkedList head , int index , int value) {
     //判断脚标是否越过下界
    if(index <= 0) {
        cout << "您要修改的结点不存在!" << endl;
        return;
    }
    //移到指针到要修改的结点处
    LinkedList curr = head;
    for(int i = 0; i < index ; i++) {
        if(curr->lNext != NULL) {
            curr = curr->lNext;
        } else {
            cout << "您要修改的结点不存在!" << endl;
            return;
        }
    }
    //修改结点值
    curr->data = value;
}

//合并两个有序链表
LinkedList mergeLinkedList(LinkedList la , LinkedList lb) {
    LinkedList laCurr = la->lNext;
    LinkedList lbCurr = lb->lNext;
    LinkedList lcCurr = la;
    //LinkedList lc = lcCurr;  //课本上设置的这个变量完全是多余的,可以去掉
    while(laCurr != NULL && lbCurr != NULL) {
        if(laCurr->data >= lbCurr->data){
            lcCurr->lNext = lbCurr;
            lcCurr = lcCurr->lNext;
            lbCurr = lbCurr->lNext;
        } else {
            lcCurr->lNext = laCurr;
            lcCurr = lcCurr->lNext;
            laCurr = laCurr->lNext;
        }
    }
    lcCurr->lNext = laCurr ? laCurr : lbCurr;
    free(lb);
    //return lc;
    return la;
}

//逆转链表
void reverseLinkedList(LinkedList lHead , LinkedList iResult) {
    //如果传入的只是个头指针,则退出运算
    if(lHead->lNext == NULL) {
        free(lHead);
        return;
    }
    //找到倒数第二个元素结点
    LinkedList tail = lHead;
    //int length = 0;
    while(tail->lNext->lNext != NULL) {
        tail = tail->lNext;
        //length ++;
    }
    //让返回的LinkedList指针,指向传入LinkedList的最后一个元素结点
    iResult->lNext = tail->lNext;
    //把倒数第二个结点设成倒数第一个结点
    tail->lNext = NULL;
    //递归调用函数
    reverseLinkedList(lHead , iResult->lNext);
    //cout << tail->data << "  " << length << endl;
}

//头插法进行逆转
void reverseList(LinkedList lHead) {
    LinkedList list1 , list2;
    //记录第二个结点
    list1 = list2 = lHead->lNext->lNext;
    lHead->lNext->lNext = NULL;
    //将第二个结点及以后的所有结点依次插入头结点之后
    while(list1 != NULL) {
        list2 = list2->lNext;
        list1->lNext = lHead->lNext;
        lHead->lNext = list1;
        list1 = list2;
    }
}
分享到:
评论

相关推荐

    数据结构 课程设计 用链表实现集合并集 c++

    本项目是关于“用链表实现集合并集”的C++课程设计,主要目的是掌握集合操作以及如何利用链表数据结构高效地实现这些操作。 首先,我们需要了解集合的基本概念。集合是一个无序且不包含重复元素的数学结构。在...

    C++ 链表实现两个一元多项式相加

    总的来说,C++中链表实现一元多项式的加法是一种巧妙而实用的方法,它结合了数据结构和算法的知识,展示了计算机科学的魅力。通过熟练掌握这样的编程技巧,不仅可以提高编程能力,还能为解决更复杂的问题打下坚实的...

    STM32用链表实现多级菜单

    综上所述,用链表实现STM32的多级菜单是一个涉及数据结构、内存管理、事件处理和用户界面设计等多个方面的综合性任务。通过熟练掌握这些知识点,我们可以创建出高效、易用且可扩展的嵌入式系统用户界面。

    用数据结构-链表实现通讯录管理系统

    本项目以"用数据结构-链表实现通讯录管理系统"为主题,通过C语言实现了这一功能,旨在帮助用户管理他们的联系人信息。下面我们将深入探讨这个系统所涉及的主要知识点。 首先,我们来了解**链表**这一数据结构。链表...

    链表实现集合运算 链表实现集合交并差运算

    链表实现集合运算 链表实现集合交并差运算

    用链表实现图书管理系统

    ### 使用链表实现图书管理系统的知识点 #### 一、链表基本概念 链表是一种常见的数据结构,由一系列节点组成,每个节点包含实际存储的数据和一个指向下一个节点的引用(指针)。在本例中,链表用于实现图书管理系统...

    用链表实现线性表java

    链表实现线性表的基本操作包括添加元素(插入)、删除元素、查找元素以及遍历等。在`ChainList.java`文件中,可能会定义一个名为`Node`的类来表示链表节点,如下所示: ```java class Node { int data; Node next...

    C语言链表实现学生信息管理

    ### 题目:C语言链表实现学生信息管理 #### 描述: 这是一个用C语言编写的简单程序,通过链表技术实现了学生信息的管理功能。用户可以通过简单的命令行界面执行各种操作,如添加、删除、修改、查询学生信息以及保存...

    C语言学生考试系统(链表实现)

    《C语言学生考试系统——链表实现》 在信息技术领域,C语言作为一种基础且强大的编程语言,被广泛用于系统编程、软件开发以及教学实训。本项目“C语言学生考试系统”便是利用C语言来实现的一个简易考试管理工具,其...

    Go-LinkedList一个简单的双链表实现

    本文将深入探讨Go语言中的双链表实现,以标题"Go-LinkedList一个简单的双链表实现"为例,我们将分析双链表的设计、操作以及其在实际应用中的价值。 双链表是一种线性数据结构,每个节点包含两个指针,分别指向前后...

    链表实现栈和队列(经典程序)

    在"delimetermach.cpp"这个源代码文件中,很可能包含了具体的链表实现栈和队列的C++代码。通过阅读和分析这段代码,我们可以深入理解如何使用C++的指针和结构体来构建链表节点,以及如何通过指针操作来实现栈的压栈...

    图书管理系统(C语言链表实现)含实验报告

    大学期间用C语言链表实现的一个图书管理系统,主要功能有 a. 设备申请。由专业人员填写“申请表”送交领导批准购买。 b. 设备入库。新设备购入后要立即进行设备登记(包括类别、设备名、型号、规格、单价、数量、...

    航空订票系统--链表实现.rar

    《航空订票系统--链表实现》 在IT行业中,航空订票系统是航空公司和旅行代理机构的关键组成部分,它负责管理航班信息、座位预订、乘客信息等重要数据。本项目着重探讨了如何利用链表这一数据结构来实现航空订票系统...

    大数相乘通用链表实现

    通用链表实现是解决这个问题的一种高效方法,它能够处理任意长度的整数,不受固定大小数据类型的限制。本篇文章将深入探讨如何利用链表结构来实现大数相乘,并分析其工作原理和优化策略。 首先,链表是一种动态数据...

    数组和链表实现队列

    5. **优缺点**:链表实现队列时,入队和出队操作通常较快,因为无需移动其他元素。但相比于数组,链表的随机访问性能较差,因为需要遍历找到特定位置的节点。 **对比与选择** 数组和链表实现队列各有优势,具体...

    c#版的双向链表实现

    总结,C#版的双向链表实现涉及到泛型、接口和类设计等多个核心编程概念。通过这些工具,我们可以创建一个灵活、高效且可复用的数据结构,以满足各种程序需求。在实际开发中,理解和掌握这些概念对于提升代码质量至关...

    账号管理系统的链表实现

    在链表实现中,可以考虑结合这两种方法,为不同的查询场景提供优化。 密码退格功能是指用户在输入密码时能撤销最近一次输入的操作。在链表实现中,可以维护一个额外的链表,用于存储用户的输入历史,每次退格操作就...

    链表实现单词本管理.docx

    C语言链表实现单词本管理 本文档主要介绍了使用C语言实现单词本管理系统的设计和实现过程。该系统使用链表结构来存储单词及其对应的中文解释,并提供了插入、删除、查找和输出单词的功能。 1. 链表结构的实现 在...

    用链表实现多项式_C++_

    总的来说,用链表实现多项式运算是一种灵活且高效的方法,它可以方便地处理任意大小的多项式,并支持各种算术操作。链表的动态特性使得这种实现方式具有很高的可扩展性,可以适应不同的问题需求。

    长整型相乘,链表实现。

    本文将深入探讨一种利用链表实现长整型相乘的算法。 链表是一种线性数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的引用。这种数据结构特别适合存储动态增长的序列,因为可以在运行时轻松添加或...

Global site tag (gtag.js) - Google Analytics