数据结构——线性表(单链表)

一、单链表

        单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个节点的构成:(元素+指针) 元素就是存储数据的存储单元,指针就是连接每个节点的地址数据。

        定义:每个结点 除了存放数据元素外,还要存储指向下一个节点的指针;

        优点:不要求大片连续空间,改变容量方便;

        缺点:不可随机存取,要耗费一定空间存放指针

        局限性:无法逆向检索

二、单链表的代码 

1、单链表的结点类型

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

2、单链表的基本操作

1、头插法建立单链表

//头插法
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、尾插法建立单链表

//尾插法
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、按序号查找结点的值

//按序号查找
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、按值查找表结点

//按值查找
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、插入结点操作

//插入
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、删除结点

//删除
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、打印链表

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

3、主程序

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

三、全部代码 

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

猜你喜欢

转载自blog.csdn.net/weixin_42823298/article/details/127123810