Data structure - linear list (singly linked list)

1. Single linked list

        A singly linked list is a chained access data structure that uses a set of storage units with arbitrary addresses to store data elements in a linear list. The data in the linked list is represented by nodes. The composition of each node is: (element + pointer). The element is the storage unit that stores the data, and the pointer is the address data connecting each node.

        Definition: In addition to storing data elements, each node also stores a pointer to the next node;

        Advantages: Does not require large continuous space, easy to change capacity;

        Disadvantages: No random access, it takes a certain amount of space to store pointers

        Limitations: Unable to reverse search

2. Code for singly linked list 

1. Node type of singly linked list

typedef int ElemType;
typedef struct LNode{       //定义单链表结点类型
    ElemType data;          //数据域
    struct LNode *next;     //指针域
}LNode,*LinkList;

2. Basic operations of singly linked list

1. Create a singly linked list using head insertion method

//头插法
LinkList CreatList1(LinkList &L){           //逆向建立单链表
    LNode *s;
    int x;
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    L->next = NULL;                         //初始值为空链
    cin>>x;                                 //输入结点的值
    while(x!=9999){                         //输入9999表示结束
        s = (LinkList)malloc(sizeof(LNode));//创建新节点
        //顺序不能改变
        s->data = x;
        s->next = L->next;                  //将新结点插入表中,L为头指针
        L->next = s;
        cin>>x;
    }
    return L;
}

 2. Create a singly linked list using tail insertion method

//尾插法
LinkList CreatList2(LinkList &L){           //正向建立单链表
    int x;                                  //设元素类型为整形
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    LNode *s,*r = L;                        //r为表尾指针
    cin>>x;                                 //输入结点的值
    while(x!=9999){                         //输入9999表示结束
        s = (LinkList)malloc(sizeof(LNode));//创建新节点
        s->data = x;
        r->next = s;
        r = s;                              //r指向新的表尾结点
        cin>>x;
    }
    r->next = NULL;                         //尾结点指针置为空
    return L;
}

3. Find the value of the node according to the serial number

//按序号查找
LNode *GetElem(LinkList L,int i){
    int j=1;                                //计数,初始值为1
    LNode *p = L->next;                     //第一个结点指针赋给P
    if(i==0){
        return L;                           //若i等于0,则返回头结点
    }
    if(i<1){
        return NULL;                        //若i无效,则返回NULL
    }
    while(p&&j<i){                          //从第一个结点开始找,查找第i个结点
        p=p->next;
        j++;
    }
    return p;                               //返回第i个结点的指针
}

4. Find table nodes by value

//按值查找
LNode *LocateElem(LinkList L,ElemType e){
    LNode *p = L->next;
    while(p!=NULL && p->data==e){       //从第1个结点开始查找data域为e的结点
        p=p->next;
    }
    return p;               //找到后返回该结点指针,否则返回NULL
}

5. Insert node operation

//插入
bool ListFroneInsert(LinkList L,int i,ElemType e){
    LNode *p = GetElem(L, i-1);     //查找插入位置的前驱结点
    if(p==NULL){
        return false;
    }
    LNode *s = (LinkList)malloc(sizeof(LNode));
    s->data = e;                    //将e的值赋值给新结点的数据域
    s->next = p->next;              //插入操作
    p->next = s;
    return true;
}

6. Delete nodes

//删除
bool ListDelete(LinkList L,int i){
    LNode *p = GetElem(L, i-1);     //查找删除位置的前驱结点
    if(p==NULL){
        return false;
    }
    LNode *q = p->next;             //将q指向被删除的结点
    p->next = q->next;              //将*q结点断开
    free(q);                        //释放结点
    q=NULL;                         //赋值NULL,防止野指针
    return true;
}

7. Print the linked list

//打印
void PrintList(LinkList L){
    L = L->next;
    while(L!=NULL){
        cout<<L->data<<" ";
        L=L->next;
    }
    cout<<endl;
}

3. Main program

int main(){
    //输入的数据3 4 5 6 7 9999
    LinkList L;
    LinkList search;
//    CreatList1(L);                    //头插法
    CreatList2(L);                      //尾插法
    PrintList(L);                       //打印链表
    //查找第二个元素
    search = GetElem(L, 2);
    cout<<search->data<<endl;
    //在第二个位置插入99
    bool res = ListFroneInsert(L,2,99);
    if(res){
        cout<<"插入成功"<<endl;
        PrintList(L);
    }else{
        cout<<"插入失败"<<endl;
        PrintList(L);
    }
    //删除第二个元素
    bool res2 = ListDelete(L,2);
    if(res){
        cout<<"删除成功"<<endl;
        PrintList(L);
    }else{
        cout<<"删除失败"<<endl;
        PrintList(L);
    }
    return 0;
}

3. All codes 

#include <bits/stdc++.h>
using namespace std;
//单链表
typedef int ElemType;
typedef struct LNode{       //定义单链表结点类型
    ElemType data;          //数据域
    struct LNode *next;     //指针域
}LNode,*LinkList;
//头插法
LinkList CreatList1(LinkList &L){           //逆向建立单链表
    LNode *s;
    int x;
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    L->next = NULL;                         //初始值为空链
    cin>>x;                                 //输入结点的值
    while(x!=9999){                         //输入9999表示结束
        s = (LinkList)malloc(sizeof(LNode));//创建新节点
        //顺序不能改变
        s->data = x;
        s->next = L->next;                  //将新结点插入表中,L为头指针
        L->next = s;
        cin>>x;
    }
    return L;
}
//尾插法
LinkList CreatList2(LinkList &L){           //正向建立单链表
    int x;                                  //设元素类型为整形
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    LNode *s,*r = L;                        //r为表尾指针
    cin>>x;                                 //输入结点的值
    while(x!=9999){                         //输入9999表示结束
        s = (LinkList)malloc(sizeof(LNode));//创建新节点
        s->data = x;
        r->next = s;
        r = s;                              //r指向新的表尾结点
        cin>>x;
    }
    r->next = NULL;                         //尾结点指针置为空
    return L;
}
//按序号查找
LNode *GetElem(LinkList L,int i){
    int j=1;                                //计数,初始值为1
    LNode *p = L->next;                     //第一个结点指针赋给P
    if(i==0){
        return L;                           //若i等于0,则返回头结点
    }
    if(i<1){
        return NULL;                        //若i无效,则返回NULL
    }
    while(p&&j<i){                          //从第一个结点开始找,查找第i个结点
        p=p->next;
        j++;
    }
    return p;                               //返回第i个结点的指针
}
//按值查找
LNode *LocateElem(LinkList L,ElemType e){
    LNode *p = L->next;
    while(p!=NULL && p->data==e){       //从第1个结点开始查找data域为e的结点
        p=p->next;
    }
    return p;               //找到后返回该结点指针,否则返回NULL
}
//插入
bool ListFroneInsert(LinkList L,int i,ElemType e){
    LNode *p = GetElem(L, i-1);     //查找插入位置的前驱结点
    if(p==NULL){
        return false;
    }
    LNode *s = (LinkList)malloc(sizeof(LNode));
    s->data = e;                    //将e的值赋值给新结点的数据域
    s->next = p->next;              //插入操作
    p->next = s;
    return true;
}
//删除
bool ListDelete(LinkList L,int i){
    LNode *p = GetElem(L, i-1);     //查找删除位置的前驱结点
    if(p==NULL){
        return false;
    }
    LNode *q = p->next;             //将q指向被删除的结点
    p->next = q->next;              //将*q结点断开
    free(q);                        //释放结点
    q=NULL;                         //赋值NULL,防止野指针
    return true;
}
//打印
void PrintList(LinkList L){
    L = L->next;
    while(L!=NULL){
        cout<<L->data<<" ";
        L=L->next;
    }
    cout<<endl;
}
int main(){
    //输入的数据3 4 5 6 7 9999
    LinkList L;
    LinkList search;
//    CreatList1(L);                    //头插法
    CreatList2(L);                      //尾插法
    PrintList(L);                       //打印链表
    //查找第二个元素
    search = GetElem(L, 2);
    cout<<search->data<<endl;
    //在第二个位置插入99
    bool res = ListFroneInsert(L,2,99);
    if(res){
        cout<<"插入成功"<<endl;
        PrintList(L);
    }else{
        cout<<"插入失败"<<endl;
        PrintList(L);
    }
    //删除第二个元素
    bool res2 = ListDelete(L,2);
    if(res){
        cout<<"删除成功"<<endl;
        PrintList(L);
    }else{
        cout<<"删除失败"<<endl;
        PrintList(L);
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_42823298/article/details/127123810