1、单链表的定义
2、单链表的实现
3、单链表的逻辑示意图
4、使用C语言来实现单链表的基本操作
5、使用C++语言来实现单链表的基本操作
6、使用java语言来实现单链表的基本操作
7、使用javaScript语言来实现单链表的基本操作
8、使用Python语言来实现单链表的基本操作

五种编程语言解释数据结构与算法—单链表

1、单链表的定义

线性表的链式存储又称为单链表,通过一组任意的存储单元来存储线性表中的数据元素。

2、单链表的实现

3、单链表的逻辑示意图

3.1、第一种逻辑方式:只有头指针,没有头结点

这种方式,当head为null时,单链表L为空。

3.2、第二种实现逻辑方式:有头结点

这种方式,当head->next为null时,单链表L为空。

优点:链表的第一个位置和其他位置的操作统一空表和非空表的操作统一。

4、使用C语言来实现单链表的基本操作

4.0、建立链表和链表结点的结构体

有单链表的性质可知,单链表中包含着结点,结点又由两部分组成,一部分为数据,一部分为下一个结点的地址。所以可以将结点定义为:

//链表结点
typedef struct LinkNode {
    void* data;     //void*     无类型指针,可以指向任何类型的数据
    struct LinkNode* next;
}LinkNode;

为了方便表述链表,这里使用有头结点的链表结构,并且需要一个int类型的变量来记录链表的长度。

//链表结构体
typedef struct LinkList {
    LinkNode* head;     //头节点
    int size;   //大小
    //不需要容量
}LinkList;

这里编写一个函数,进行链表的初始化操作。

//初始化链表
 LinkList* Init_LinkList() {
    LinkList* list = (LinkList*)malloc(sizeof(LinkList));
    list->size = 0;
    //头节点,不保存数据信息
    list->head = (LinkNode*)malloc(sizeof(LinkNode));
    list->head->data = NULL;
    list->head->next = NULL;
     return list;
}

4.1、头插法建立单链表

由图可以看出,想要实现头插入操作时,只需要将上一个结点的地址指向要插入结点的头部,而将要插入结点的地址指针指向原先上一个结点指向的地址即可。该头插法插入的特点为,后面插入的元素在链表的头部。

//头插法建立单链表
LinkList* List_HeadInsert(int size) {
    //创建链表
    LinkList* list = Init_LinkList();
    //用户输入size个整数
    int x;
    scanf("%d\n",&x);
    LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));

    for(int i = 0;i < size;i++) {
        //初始化一个结点
        LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
        scanf("%d\n",&x);
        newNode->data = &x;
        newNode->next = list->head->next;
        list->head->next = newNode;
        list->size++;
    }
    return list;
}

该算法的时间复杂度为O(n)

4.2、尾插法建立单链表

使用尾插法建立单链表,就是在尾部进行链表结点的加入,使得辅助指针后移,实现尾部插入。该插入方法的特点为,后来的元素在链表后面。

//尾插法
LinkList* List_TailInsert(int size) {
    //创建链表
    LinkList* list = Init_LinkList();
    //用户输入size个整数
    int x;
    scanf("%d\n",&x);
    LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));

    //找结点
    //辅助指针变量
    LinkNode* pCurrent = list->head;
    for(int i = 0; i < size;i++) {
        pCurrent = pCurrent->next;
    }

    for(int i = 0;i < size;i++) {
        //初始化一个结点
        LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
        scanf("%d\n",&x);
        newNode->data = &x;
        newNode->next = NULL;

        //遍历完后,辅助指针就指向的是最后一个结点
        pCurrent->next = newNode;
        pCurrent = pCurrent->next;
        list->size++;
    }
    return list;
}

该算法的时间复杂度为O(n)

4.3、按序号查找和按值查找

按序号查找,就是通过辅助指针遍历到需要查找的序号的位置,并且将该结点进行返回,代码如下。

//按序号查找
LinkNode* getElem(LinkList* list,int pos) {
    if(list == NULL) return NULL;
    if(pos == 0) return list->head;
    if(pos < 1 || pos > list->size) return NULL;

    //找结点
    //辅助指针变量
    LinkNode* pCurrent = list->head->next;
    //遍历查找
    for(int i = 0; i < pos - 1;i++) {
        pCurrent = pCurrent->next;
    }
    return pCurrent;
}

按值查找,就是循环遍历整个链表,然后于传入的值进行匹配,如果相等,则返回该结点。

//查找
int Find_LinkList(LinkList* list,void* data) {
    if(list == NULL) return -1;
    if(data == NULL) return -1;
    //定义辅助指针
    LinkNode* pCurrent = list->head->next;
    for(int i = 1;i <= list->size;i++) {
        if(pCurrent->data == data) {
            return i;
        }
        pCurrent = pCurrent->next;
    }
    return -1;
}

这两个查找的算法都为O(n)

4.4、插入新结点的操作

右图可以看出,插入操作以头插法建立单链表的操作几乎一样,只不过在这里是把头结点替换成了任意结点。

//插入
void Insert_LinkList(LinkList* list, int pos,void* data) {
    if(list == NULL) return;
    if(data == NULL) return;

    //将用户的从1开始排序,转换成为程序员理解的从0开始排序
    pos = pos - 1;

    if(pos < 0 || pos > list->size) return;

    //创建新的结点
    LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
    newNode->data = data;
    newNode->next = NULL;

    //找结点
    //辅助指针变量
    LinkNode* pCurrent = list->head;
    for(int i = 0; i < pos;i++) {
        pCurrent = pCurrent->next;
    }

    //新节点入链表
    newNode->next = pCurrent->next;
    pCurrent->next = newNode;

    list->size++;

}

4.5、删除结点的操作

在单链表中,如果要删除一个结点,只需要将待删除结点的前一个结点指向待删除结点的下一个结点即可。

//删除指定位置的值
void RemoveByPos_LinkList(LinkList* list,int pos) {
    if(list == NULL) return;
    if(pos < 1 || pos > list->size) return;

    //找结点
    //辅助指针变量
    LinkNode* pCurrent = list->head;
    //指向前一个结点
    for(int i = 1; i < pos;i++) {
        pCurrent = pCurrent->next;
    }

    //缓存删除的结点
    LinkNode* pDel = pCurrent->next;
    pCurrent->next = pDel->next;
    //释放删除结点的内存
    free(pDel);

    list->size--;
}

4.6、完整代码

  1. LinkList.h文件中的内容,该文件内容定义了该单链表具有的方法

    #ifndef XGP_STUDY_DEMO40_LINKLIST_H
    #define XGP_STUDY_DEMO40_LINKLIST_H
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //链表结点
    typedef struct LinkNode {
        void* data;     //void*     无类型指针,可以指向任何类型的数据
        struct LinkNode* next;
    }LinkNode;
    
    //链表结构体
    typedef struct LinkList {
        LinkNode* head;     //头节点
        int size;   //大小
        //不需要容量
    }LinkList;
    
    typedef void(*PRINTLINKNODE)(void*);
    
    //初始化链表
    LinkList* Init_LinkList();
    //插入错作
    void Insert_LinkList(LinkList* list, int pos,void* data);
    //头插法建立整数型单链表
    LinkList* List_HeadInsert(int size);
    //尾插法
    LinkList* List_TailInsert(int size);
    //按序号查找
    LinkNode* getElem(LinkList* list,int pos);
    //按值查找
    int Find_LinkList(LinkList* list,void* data);
    //删除指定位置的值
    void RemoveByPos_LinkList(LinkList* list,int pos);
    //获得链表的长度
    int Size_LinkList(LinkList* list);
    //释放链表内存
    void FreeSpace_LinkList(LinkList* list);
    //打印
    void Print_LinkList(LinkList* list,PRINTLINKNODE print);
    #endif //XGP_STUDY_DEMO40_LINKLIST_H
  2. LinkList.c文件的内容,该内容是对上述头文件中的方法做具体得实现。

    #include "LinkList.h"
    
    //初始化链表
     LinkList* Init_LinkList() {
        LinkList* list = (LinkList*)malloc(sizeof(LinkList));
        list->size = 0;
        //头节点,不保存数据信息
        list->head = (LinkNode*)malloc(sizeof(LinkNode));
        list->head->data = NULL;
        list->head->next = NULL;
         return list;
    }
    
    //插入
    void Insert_LinkList(LinkList* list, int pos,void* data) {
        if(list == NULL) return;
        if(data == NULL) return;
    
        //将用户的从1开始排序,转换成为程序员理解的从0开始排序
        pos = pos - 1;
    
        if(pos < 0 || pos > list->size) return;
    
        //创建新的结点
        LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
        newNode->data = data;
        newNode->next = NULL;
    
        //找结点
        //辅助指针变量
        LinkNode* pCurrent = list->head;
        for(int i = 0; i < pos;i++) {
            pCurrent = pCurrent->next;
        }
    
        //新节点入链表
        newNode->next = pCurrent->next;
        pCurrent->next = newNode;
    
        list->size++;
    
    }
    
    //头插法建立单链表
    LinkList* List_HeadInsert(int size) {
        //创建链表
        LinkList* list = Init_LinkList();
        //用户输入size个整数
        int x;
        scanf("%d\n",&x);
        LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
    
        for(int i = 0;i < size;i++) {
            //初始化一个结点
            LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
            scanf("%d\n",&x);
            newNode->data = &x;
            newNode->next = list->head->next;
            list->head->next = newNode;
            list->size++;
        }
        return list;
    }
    
    //尾插法
    LinkList* List_TailInsert(int size) {
        //创建链表
        LinkList* list = Init_LinkList();
        //用户输入size个整数
        int x;
        scanf("%d\n",&x);
        LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
    
        //找结点
        //辅助指针变量
        LinkNode* pCurrent = list->head;
        for(int i = 0; i < size;i++) {
            pCurrent = pCurrent->next;
        }
    
        for(int i = 0;i < size;i++) {
            //初始化一个结点
            LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
            scanf("%d\n",&x);
            newNode->data = &x;
            newNode->next = NULL;
    
            //遍历完后,辅助指针就指向的是最后一个结点
            pCurrent->next = newNode;
            pCurrent = pCurrent->next;
            list->size++;
        }
        return list;
    }
    
    //按序号查找
    LinkNode* getElem(LinkList* list,int pos) {
        if(list == NULL) return NULL;
        if(pos == 0) return list->head;
        if(pos < 1 || pos > list->size) return NULL;
    
        //找结点
        //辅助指针变量
        LinkNode* pCurrent = list->head->next;
        //遍历查找
        for(int i = 0; i < pos - 1;i++) {
            pCurrent = pCurrent->next;
        }
        return pCurrent;
    }
    
    //查找
    int Find_LinkList(LinkList* list,void* data) {
        if(list == NULL) return -1;
        if(data == NULL) return -1;
        //定义辅助指针
        LinkNode* pCurrent = list->head->next;
        for(int i = 1;i <= list->size;i++) {
            if(pCurrent->data == data) {
                return i;
            }
            pCurrent = pCurrent->next;
        }
        return -1;
    }
    
    //删除指定位置的值
    void RemoveByPos_LinkList(LinkList* list,int pos) {
        if(list == NULL) return;
        if(pos < 1 || pos > list->size) return;
    
        //找结点
        //辅助指针变量
        LinkNode* pCurrent = list->head;
        //指向前一个结点
        for(int i = 1; i < pos;i++) {
            pCurrent = pCurrent->next;
        }
    
        //缓存删除的结点
        LinkNode* pDel = pCurrent->next;
        pCurrent->next = pDel->next;
        //释放删除结点的内存
        free(pDel);
    
        list->size--;
    }
    //打印
    void Print_LinkList(LinkList* list,PRINTLINKNODE print) {
        if(list == NULL) return;
        //定义辅助指针变量
        LinkNode* pCurrent = list->head->next;
        for(int i = 0;i < list->size;i++) {
            print(pCurrent->data);
            pCurrent = pCurrent->next;
        }
    }
    
    //释放链表内存
    void FreeSpace_LinkList(LinkList* list) {
        if(list == NULL) return;
        //辅助指针变量
        LinkNode* pCurrent = list->head;
    
        for(int i = 0;i <= list->size;i++) {
            //缓存下一个结点
            LinkNode* pNext = pCurrent->next;
            free(pCurrent);
            pCurrent = pNext;
        }
    
        //释放链表内存
        list->size = 0;
        free(list);
    
    }
    
    //获得链表的长度
    int Size_LinkList(LinkList* list) {
        if(list == NULL)return -1;
        return list->size;
    }
  3. main.c文件中的内容,该内容的代码是用来测试该单链表中的方法。

    #include "LinkList.h"
    
    typedef struct Person {
        char name[64];
        int age;
        int score;
    }Person;
    
    void MyPrint(void* data) {
        Person* p = (Person*)data;
        printf("Name:%s Age:%d Score:%d\n",p->name,p->age,p->score);
    }
    
    int main() {
    
        //创建链表
        LinkNode* list = Init_LinkList();
    
        //创建数据
        Person p1 = {"aaa",23,80};
        Person p2 = {"bbb",24,81};
        Person p3 = {"ccc",25,82};
        Person p4 = {"ddd",26,83};
        Person p5 = {"eee",27,84};
    
        //数据插入链表
        Insert_LinkList(list,0,&p1);
        Insert_LinkList(list,1,&p2);
        Insert_LinkList(list,2,&p3);
        Insert_LinkList(list,3,&p4);
        Insert_LinkList(list,4,&p5);
    
        //打印
        Print_LinkList(list,MyPrint);
    
        printf("==========================\n");
    
        //删除
        RemoveByPos_LinkList(list,3);
        Print_LinkList(list,MyPrint);
    
        //销毁链表
        FreeSpace_LinkList(list);
        return 0;
    }
  4. 测试结果

    Name:bbb Age:24 Score:81
    Name:ccc Age:25 Score:82
    Name:ddd Age:26 Score:83
    Name:eee Age:27 Score:84
    ==========================
    Name:bbb Age:24 Score:81
    Name:ccc Age:25 Score:82
    Name:eee Age:27 Score:84
    
    Process finished with exit code 0

5、使用C++语言来实现单链表的基本操作

  1. MyLinkList.h文件的内容
#ifndef XGP_STUDY_DEMO43_MYLINKLIST_H
#define XGP_STUDY_DEMO43_MYLINKLIST_H

#include <iostream>
using namespace std;

typedef void(*PRINTLINKNODE)(void*);

template <class T>
class MyLinkNode {
public:
        T* data;     //存放T类型的数据
        MyLinkNode* next;    //下一个结点
};

template <class T>
class MyLinkList {
    private:
        MyLinkNode<T>* head;     //头节点
        int size;   //大小
    public:

    //初始化链表
        MyLinkList Init_LinkList();
    //插入错作
        void Insert_LinkList(int pos,T* data);
    //头插法建立整数型单链表
        MyLinkList List_HeadInsert(int size);
    //尾插法
        MyLinkList List_TailInsert(int size);
    //按序号查找
        MyLinkNode<T> getElem(int pos);
    //按值查找
        int Find_LinkList(T data);
    //删除指定位置的值
        void RemoveByPos_LinkList(int pos);
    //获得链表的长度
        int Size_LinkList();
    //释放链表内存
        void FreeSpace_LinkList();
    //打印
        void Print_LinkList(PRINTLINKNODE print);

};

#endif //XGP_STUDY_DEMO43_MYLINKLIST_H
  1. MyLinkList.cpp文件内容
#include "MyLinkList.h"

template<class T>
MyLinkList<T> MyLinkList<T>::Init_LinkList() {
    MyLinkNode<T>* node = new MyLinkNode<T>();
    node->data = NULL;
    node->next = NULL;
    this->head = node;
    this->size = 0;
    return *this;
}

template<class T>
void MyLinkList<T>::Insert_LinkList(int pos, T* data) {
    if(this == NULL) return;
    if(data == NULL) return;

    MyLinkNode<T>* newNode = new MyLinkNode<T>();
    newNode->data = data;
    newNode->next = NULL;

    //插入,找到一个指向pos-1的结点来的辅助指针
    MyLinkNode<T>* pCurrent = this->head;
    for(int i = 1;i <= pos - 1;i++) {
        pCurrent = pCurrent->next;
    }
    //循环过后,此时的辅助结点就是插入结点的前一个
    newNode->next = pCurrent->next;
    pCurrent->next = newNode;

    this->size++;
}

template<class T>
MyLinkList<T> MyLinkList<T>::List_HeadInsert(int size) {
    //用户输入size个整数
    int x;
    scanf("%d\n",&x);
    MyLinkNode<T>* newNode = new MyLinkNode<T>();

    for(int i = 0;i < size;i++) {
        //初始化一个结点
        MyLinkNode<T>* newNode = new MyLinkNode<T>();
        scanf("%d\n",&x);
        newNode->data = &x;
        newNode->next = this->head->next;
        this->head->next = newNode;
        this->size++;
    }
    return *this;
}

template<class T>
MyLinkList<T> MyLinkList<T>::List_TailInsert(int size) {
    //用户输入size个整数
    int x;
    scanf("%d\n",&x);
    MyLinkNode<T>* newNode = new MyLinkNode<T>();

    //找结点
    //辅助指针变量
    MyLinkNode<T>* pCurrent = this->head;
    for(int i = 0; i < size;i++) {
        pCurrent = pCurrent->next;
    }

    for(int i = 0;i < size;i++) {
        //初始化一个结点
        MyLinkNode<T>* newNode = new MyLinkNode<T>;
        scanf("%d\n",&x);
        newNode->data = &x;
        newNode->next = NULL;

        //遍历完后,辅助指针就指向的是最后一个结点
        pCurrent->next = newNode;
        pCurrent = pCurrent->next;
        this->size++;
    }
    return *this;
}

template<class T>
MyLinkNode<T> MyLinkList<T>::getElem(int pos) {
    if(pos < 1 || pos >= this->size) new MyLinkNode<T>();

    MyLinkNode<T>* pCurrent = this->head;
    //辅助指针
    for(int i = 1;i <= pos;i++) {
        pCurrent = pCurrent->next;
    }
    return *pCurrent;
}

template<class T>
int MyLinkList<T>::Find_LinkList(T data) {
    if(data == NULL) return -1;
    //定义辅助指针变量
    MyLinkNode<T>* pCurrent = this->head->next;
    for(int i = 1;i <= this->size;i++) {
        if(pCurrent->data == data) {
            return i;
        }
        pCurrent = pCurrent->next;
    }
    return 0;
}

template<class T>
void MyLinkList<T>::RemoveByPos_LinkList(int pos) {
    if(this == NULL) return;
    if(pos < 1 || pos > this->size) return;

    //找结点
    //辅助指针变量
    MyLinkNode<T>* pCurrent = this->head;
    //指向前一个结点
    for(int i = 1; i < pos;i++) {
        pCurrent = pCurrent->next;
    }

    //缓存删除的结点
    MyLinkNode<T>* pDel = pCurrent->next;
    pCurrent->next = pDel->next;
    //释放删除结点的内存
    delete pDel;

    this->size--;
}

template<class T>
int MyLinkList<T>::Size_LinkList() {
    if(this == NULL) return -1;
    return this->size;
}

template<class T>
void MyLinkList<T>::FreeSpace_LinkList() {
    //辅助指针变量
    MyLinkNode<T>* pCurrent = this->head;

    for(int i = 0;i <= this->size;i++) {
        //缓存下一个结点
        MyLinkNode<T>* pNext = pCurrent->next;
        delete pNext;
        pCurrent = pNext;
    }

    //释放链表内存
    this->head = NULL;
    this->size = 0;

    delete this;
}


template<class T>
void MyLinkList<T>::Print_LinkList(PRINTLINKNODE print) {
    if(this == NULL) return;
    //定义辅助指针变量
    MyLinkNode<T>* pCurrent = this->head->next;
    for(int i = 0;i < this->size;i++) {
        print(pCurrent->data);
        pCurrent = pCurrent->next;
    }
}
  1. main.cpp的内容
#include <ostream>
#include "MyLinkList.cpp"

class Person {
public:
    string name;
    int age;
    int score;

    Person(const string &name, int age, int score) : name(name), age(age), score(score) {}

};

void MyPrint(void* data) {
    Person* p = (Person*)data;
    cout<<p->name<<"\t"<<p->age<<"\t"<<p->score<<endl;
}

int main() {
    MyLinkList<Person> list;
    list = list.Init_LinkList();

    //创建数据
    Person p1("aaa",23,80);
    Person p2("bbb",24,81);
    Person p3("ccc",25,82);
    Person p4("ddd",26,83);
    Person p5("eee",27,84);

    //插入
    list.Insert_LinkList(1,&p1);
    list.Insert_LinkList(2,&p2);
    list.Insert_LinkList(3,&p3);
    list.Insert_LinkList(4,&p4);
    list.Insert_LinkList(5,&p5);

    //输出
    list.Print_LinkList(MyPrint);

    cout<<"================"<<endl;

    MyPrint(list.getElem(3).data);

    //销毁链表
    list.FreeSpace_LinkList();
    return 0;
}
  1. 输出结果
aaa     23      80
bbb     24      81
ccc     25      82
ddd     26      83
eee     27      84
================
ccc     25      82

Process finished with exit code 0

6、使用java语言来实现单链表的基本操作

  1. MyLinkNode类的编写:
package com.xgp.单链表;

public class MyLinkNode<T> {

    T data; //存放T类型的数据
    MyLinkNode<T> next;    //下一个结点的数据地址

    @Override
    public String toString() {
        return "MyLinkNode{" +
                "data=" + data +
                '}';
    }
}
  1. MyLinkList类的编写
package com.xgp.单链表;

public interface MyLinkList<T> {
    //初始化链表
    MyLinkList Init_LinkList();
    //插入错作
    void Insert_LinkList(int pos,T data);
    //头插法建立整数型单链表
    MyLinkList List_HeadInsert(int size);
    //尾插法
    MyLinkList List_TailInsert(int size);
    //按序号查找
    MyLinkNode<T> getElem(int pos);
    //按值查找
    int Find_LinkList(T data);
    //删除指定位置的值
    void RemoveByPos_LinkList(int pos);
    //获得链表的长度
    int Size_LinkList();
    //释放链表内存
    void FreeSpace_LinkList();
    //打印
    void Print_LinkList();
}
  1. MyLinkListImpl类的编写
package com.xgp.单链表;

import java.util.Scanner;

public class MyLinkListImpl<T> implements MyLinkList<T> {

    private MyLinkNode<T> head; //头结点
    private int size;           //大小

    @Override
    public MyLinkList Init_LinkList() {
        MyLinkNode<T> node = new MyLinkNode<>();
        node.data = null;
        node.next = null;
        this.head = node;
        this.size = 0;
        return this;
    }

    @Override
    public void Insert_LinkList(int pos, T data) {
        if(data == null) return;
        if(pos < 1 || pos > this.size + 1) return;

        MyLinkNode<T> newNode = new MyLinkNode<>();
        newNode.data = data;
        newNode.next = null;

        MyLinkNode<T> pCurrent = this.head;
        for(int i = 1;i < pos;i++) {
            pCurrent = pCurrent.next;
        }

        newNode.next = pCurrent.next;
        pCurrent.next = newNode;

        this.size++;
    }

    @Override
    public MyLinkList List_HeadInsert(int size) {
        Scanner scanner = new Scanner(System.in);
        int x;

        for(int i = 1;i <= size;i++) {
            x = scanner.nextInt();
            MyLinkNode newNode = new MyLinkNode();
            newNode.data = x;
            newNode.next = this.head.next;
            this.head.next = newNode;
            this.size++;
        }
        return this;
    }

    @Override
    public MyLinkList List_TailInsert(int size) {
        Scanner scanner = new Scanner(System.in);
        int x;
        //寻找到最后一个结点
        MyLinkNode pCurrent = this.head;
        for(int i = 1;i <= this.size;i++) {
            pCurrent = pCurrent.next;
        }

        for(int i = 1;i <= size;i++) {
            x = scanner.nextInt();
            MyLinkNode newNode = new MyLinkNode();
            newNode.data = x;
            newNode.next = null;
            pCurrent.next = newNode;
            pCurrent = pCurrent.next;
            this.size++;
        }
        return this;
    }

    @Override
    public MyLinkNode<T> getElem(int pos) {
        if(pos < 1 || pos > this.size) return null;

        //找该结点
        MyLinkNode<T> pCurrent = this.head;
        for(int i = 1;i <= pos;i++) {
            pCurrent = pCurrent.next;
        }

        return pCurrent;
    }

    @Override
    public int Find_LinkList(T data) {
        if(data == null) return -1;
        //找该结点
        MyLinkNode<T> pCurrent = this.head;
        for(int i = 1;i <= this.size;i++) {
            pCurrent = pCurrent.next;
            if(pCurrent.data == data) {
                return i;
            }
        }
        return 0;
    }

    @Override
    public void RemoveByPos_LinkList(int pos) {
        if(pos < 1 || pos > this.size) return;

        //找到该结点的前一个结点
        MyLinkNode<T> pCurrent = this.head;
        for(int i = 1;i < pos;i++) {
            pCurrent = pCurrent.next;
        }

        //删除结点
        MyLinkNode<T> saveNode = pCurrent.next;
        pCurrent.next = pCurrent.next.next;
        saveNode.data = null;
        saveNode.next = null;
        this.size--;
        System.gc();
    }

    @Override
    public int Size_LinkList() {
        return this.size;
    }

    @Override
    public void FreeSpace_LinkList() {
        this.head = null;
        this.size = 0;
        System.gc();
    }

    @Override
    public void Print_LinkList() {
        MyLinkNode<T> pCurrent = this.head;

        for(int i = 1;i <= this.size;i++) {
            pCurrent = pCurrent.next;
            System.out.println(pCurrent.data);
        }
    }
}
  1. Person类的编写
package com.xgp.单链表;

public class Person {
    private String name;
    private int age;
    private int score;

    public Person(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}
  1. Main类的编写
package com.xgp.单链表;

public class Main {
    public static void main(String[] args) {
        MyLinkList<Person> list = new MyLinkListImpl<>();
        list.Init_LinkList();

        //创建数据
        Person p1 = new Person("aaa",23,80);
        Person p2 = new Person("bbb",24,81);
        Person p3 = new Person("ccc",25,82);
        Person p4 = new Person("ddd",26,83);
        Person p5 = new Person("eee",27,84);

        list.Insert_LinkList(1,p1);
        list.Insert_LinkList(2,p2);
        list.Insert_LinkList(3,p3);
        list.Insert_LinkList(4,p4);
        list.Insert_LinkList(5,p5);

        list.Print_LinkList();

        System.out.println("===================");

        list.RemoveByPos_LinkList(3);
        list.Print_LinkList();

        list.FreeSpace_LinkList();
    }
}
  1. 输出结果
Person{name='aaa', age=23, score=80}
Person{name='bbb', age=24, score=81}
Person{name='ccc', age=25, score=82}
Person{name='ddd', age=26, score=83}
Person{name='eee', age=27, score=84}
===================
Person{name='aaa', age=23, score=80}
Person{name='bbb', age=24, score=81}
Person{name='ddd', age=26, score=83}
Person{name='eee', age=27, score=84}

进程完成,退出码 0

7、使用javaScript语言来实现单链表的基本操作

  1. MyLinkList.js文件中的内容
class Person {
    constructor(name,age,score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    print() {
        return "name:" + this.name + ",age: " + this.age + ",score:" + this.score;
    }
}

//创建结点类
class LinkNode {

}

class LinkList {
        //初始化链表
        Init_LinkList() {
            var node = new LinkNode();
            node.data = null;
            node.next = null;
            this.head = node;
            this.size = 0;
            return this;
        }
        //插入错作
        Insert_LinkList(pos,data) {
            if(data == null) return;
            if(pos < 1 || pos > this.size + 1) return;
            //建立新结点
            var newNode = new LinkNode();
            newNode.data = data;
            newNode.next = null;
            //建立辅助指针
            var pCurrent = this.head;
            for(var i = 1;i < pos;i++) {
                pCurrent = pCurrent.next;
            }
            //遍历结束后,辅助指针指向的是pos-1
            newNode.next = pCurrent.next;
            pCurrent.next = newNode;
            this.size++;
        }

        //头插法建立整数型单链表
        List_HeadInsert(size) {
            for(var i = 1;i <= size;i++) {
                var newNode = new LinkNode();
                newNode.data = i;
                newNode.next = this.head.next;
                this.head.next = newNode;
                this.size++;
            }
            return this;
        }
        //尾插法
        List_TailInsert(size) {
            //建立辅助指针,指向最后一个元素
            var pCurrent = this.head;
            for(var i = 1;i <= this.size;i++) {
                pCurrent = pCurrent.next;
            }

            for(var i = 1;i <= size;i++) {
                var newNode = new LinkNode();
                newNode.data = i;
                newNode.next = null;
                pCurrent.next = newNode;
                pCurrent = pCurrent.next;
                this.size++;
            }
            return this;
        }
        //按序号查找
        getElem(pos) {
            if(pos < 1 || pos > this.size) return null;
            var pCurrent = this.head;

            for(var i = 1;i <= pos;i++) {
                pCurrent = pCurrent.next;
            }

            return pCurrent.data;
        }
        //按值查找
        Find_LinkList(data) {
            if(data == null) return -1;
            var pCurrent = this.head;

            for(var i = 1;i <= this.size;i++) {
                pCurrent = pCurrent.next;
                if(pCurrent.data == data) {
                    return i;
                }
            }

            return 0;
        }
        //删除指定位置的值
        RemoveByPos_LinkList(pos) {
            if(pos < 1 || pos > this.size) return null;
            var pCurrent = this.head;

            //找到前一个结点
            for(var i = 1;i < pos;i++) {
                pCurrent = pCurrent.next;
            }

            var saveNode = pCurrent.next;
            pCurrent.next = saveNode.next;
            saveNode.next = null;

            this.size--;
        }
        //获得链表的长度
        Size_LinkList() {
            if(this == null) return -1;
            return this.size;
        }
        //释放链表内存
        FreeSpace_LinkList() {
            this.head = null;
            this.size = 0;
            delete this;
        }
        //打印
        Print_LinkList() {
            var pCurrent = this.head;

            // var str = "";
            for(var i = 1;i <= this.size;i++) {
                pCurrent = pCurrent.next;
                // console.log(pCurrent.data);
                console.log(pCurrent.data.print());
            }
            // console.log(str);
        }
}
  1. MyLinkList.html 文件中的内容
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="MyLinkList.js"></script>
</head>
<body>
    <script>
        var list = new LinkList();
        list.Init_LinkList();

        //创建数据
        var p1 = new Person("aaa",23,80);
        var p2 = new Person("bbb",24,81);
        var p3 = new Person("ccc",25,82);
        var p4 = new Person("ddd",26,83);
        var p5 = new Person("eee",27,84);

        //插入数据
        list.Insert_LinkList(1,p1);
        list.Insert_LinkList(2,p2);
        list.Insert_LinkList(3,p3);
        list.Insert_LinkList(4,p4);
        list.Insert_LinkList(5,p5);

        //打印
        list.Print_LinkList();
        console.log(list.Size_LinkList());

        console.log(list.getElem(3));

        console.log(list.Find_LinkList(p4));

        console.log("==========================");
        list.RemoveByPos_LinkList(2);
        list.Print_LinkList();

        //销毁
        list.FreeSpace_LinkList();

    </script>
</body>
</html>
  1. 输出结果
name:aaa,age: 23,score:80 MyLinkList.js:135:25
name:bbb,age: 24,score:81 MyLinkList.js:135:25
name:ccc,age: 25,score:82 MyLinkList.js:135:25
name:ddd,age: 26,score:83 MyLinkList.js:135:25
name:eee,age: 27,score:84 MyLinkList.js:135:25
5 MyLinkList.html:30:17
Object { name: "ccc", age: 25, score: 82 }
MyLinkList.html:32:17
4 MyLinkList.html:34:17
========================== MyLinkList.html:36:17
name:aaa,age: 23,score:80 MyLinkList.js:135:25
name:ccc,age: 25,score:82 MyLinkList.js:135:25
name:ddd,age: 26,score:83 MyLinkList.js:135:25
name:eee,age: 27,score:84 MyLinkList.js:135:25

8、使用Python语言来实现单链表的基本操作

  1. MyLinkList.py 文件的内容编写
# 定义一个Person类
class Person:
    def __init__(self,name,age,score):
        self.name = name
        self.age = age
        self.score = score

    def toString(self):
        print("name: ",self.name,",age:",self.age,",score:",self.score)

class LinkNode:
    pass

class LinkList:

    # 初始化链表
    def Init_LinkList(self):
        node = LinkNode()
        node.data = None
        node.next = None
        self.head = node
        self.size = 0
        return self

    # 插入错作
    def Insert_LinkList(self,pos,data):
        if(data == None):
            return
        if(pos < 1 or pos > self.size + 1):
            return
        # 创立待插入的新节点
        newNode = LinkNode()
        newNode.data = data
        newNode.next = None
        # 辅助指针
        pCurrent = self.head
        for i in range(1,pos):
            pCurrent = pCurrent.next
        # 进行插入
        newNode.next = pCurrent.next
        pCurrent.next = newNode
        self.size += 1

    # 头插法建立整数型单链表
    def List_HeadInsert(self,size):
        for i in range(1,size + 1):
            newNode = LinkNode()
            newNode.data = i
            newNode.next = self.head.next
            self.head.next = newNode
            self.size += 1
        return self

    # 尾插法
    def List_TailInsert(self,size):
        pCurrent = self.head
        for i in range(1,self.size + 1):
            pCurrent = pCurrent.next
        for i in range(1,size + 1):
            newNode = LinkNode()
            newNode.data = i
            newNode.next = None
            pCurrent.next = newNode
            pCurrent = pCurrent.next
            self.size += 1
        return self

    # 按序号查找
    def getElem(self,pos):
        if(pos < 1 or pos > self.size):
            return None
        pCurrent = self.head
        for i in range(1,pos+1):
            pCurrent = pCurrent.next
        return pCurrent.data

    # 按值查找
    def Find_LinkList(self,data):
        if(data == None):
            return -1
        pCurrent = self.head
        for i in range(1,self.size + 1):
            pCurrent = pCurrent.next
            if(pCurrent.data == data):
                return i
        return 0

    # 删除指定位置的值
    def RemoveByPos_LinkList(self,pos):
        if(pos < 1 or pos > self.size):
            return None
        pCurrent = self.head
        for i in range(1,pos):
            pCurrent = pCurrent.next
        saveNode = pCurrent.next
        pCurrent.next = saveNode.next
        saveNode.next = None
        self.size -= 1

    # 获得链表的长度
    def Size_LinkList(self):
        if(self == None):
            return -1
        return self.size

    # 释放链表内存
    def FreeSpace_LinkList(self):
        self.head = None
        self.size = 0

    # 打印
    def Print_LinkList(self):
        pCurrent = self.head

        for i in range(1,self.size + 1):
            pCurrent = pCurrent.next
            p = pCurrent.data
            p.toString()
  1. main.py文件内容的编写
from MyLinkList import *

list = LinkList()
list.Init_LinkList();

# 创建数据
p1 = Person("aaa", 23, 80)
p2 = Person("bbb", 24, 81)
p3 = Person("ccc", 25, 82)
p4 = Person("ddd", 26, 83)
p5 = Person("eee", 27, 84)

#  插入数据
list.Insert_LinkList(1, p1)
list.Insert_LinkList(2, p2)
list.Insert_LinkList(3, p3)
list.Insert_LinkList(4, p4)
list.Insert_LinkList(5, p5)

# 打印
list.Print_LinkList()
print(list.Size_LinkList())
print(list.getElem(3))
print(list.Find_LinkList(p4))
print("=================")
list.RemoveByPos_LinkList(2)
list.Print_LinkList()

list.FreeSpace_LinkList()
  1. 输出结果
name:  aaa ,age: 23 ,score: 80
name:  bbb ,age: 24 ,score: 81
name:  ccc ,age: 25 ,score: 82
name:  ddd ,age: 26 ,score: 83
name:  eee ,age: 27 ,score: 84
5
<MyLinkList.Person object at 0x039050B0>
4
=================
name:  aaa ,age: 23 ,score: 80
name:  ccc ,age: 25 ,score: 82
name:  ddd ,age: 26 ,score: 83
name:  eee ,age: 27 ,score: 84

Process finished with exit code 0

版权声明:本文为xgp123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xgp123/p/12372611.html