データ構造 - 線形リスト(単結合リスト)

1. 単一リンクリスト

        単一リンク リストは、任意のアドレスを持つ一連のストレージ ユニットを使用してデータ要素を線形リストに格納する、連鎖アクセスデータ構造です。リンクリストのデータはノードで表現され、各ノードの構成は(要素+ポインタ)であり、要素はデータを格納する記憶単位、ポインタは各ノードを接続するアドレスデータである。

        定義: データ要素を格納することに加えて、各ノードは次のノードへのポインタも格納します。

        利点:大きな連続スペースを必要とせず、容量の変更が簡単。

        短所: ランダムアクセスができないため、ポインタを保存するために一定量のスペースが必要です。

        制限事項: 逆方向検索はできません

2. 単一リンクリストのコード 

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

3. すべてのコード 

#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