单链表

单链表

线性表的链式存储结构。
优点是链式存储的空间分配灵活、高效。
链表只能从表头顺序存取元素,能够较为快速的插入删除元素,并且不需要移动元素。
另外,链式存储结构可以更方便的表示各种逻辑结构。

代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef struct LNode{
    int data;
    struct LNode *next;
}LNode, *LinkList;

/*

上述代码等价
先定义结点
struct LNode{
    int data;
    struct LNode *next;
}
后重命名
typedef struct LNode LNode;//结点
typedef struct LNode *LinkList;//链表

*/

//初始化带头结点的单链表
bool InitList(LinkList &L){
    L = (LNode *)malloc(sizeof(LNode));//分配一个头结点
    if (L == NULL)
        return false;
    L->next = NULL;
    return true;
}

/*

//初始化无头结点的单链表
bool InitList(LinkList &L){
    L = NULL;
    return true;
}

*/

//头插法(链表的逆置)
LinkList List_HeadInsert(LinkList &L){
    LNode *s; int x;
    L = (LinkList)malloc(sizeof(LNode));//创建头结点
    L->next = NULL;
    scanf("%d", &x);
    while(x != 9999){
        s = (LNode*)malloc(sizeof(LNode));//创建新结点
        s->data = x;
        s->next = L->next; 
        L->next = s;//将新结点插入链表中,L为头指针
        scanf("%d", &x);
    }
    return L;
}

//尾插法
LinkList List_TailInsert(LinkList &L){
    int x;
    L = (LinkList)malloc(sizeof(LNode));
    LNode *s,*r = L;//r为尾指针
    scanf("%d", &x);
    while (x != 9999){
        s = (LNode*)malloc(sizeof(LNode));
        s->data = x;
        r->next = s;
        r = s;//永远保持r指向最后一个结点
        scanf("%d", &x);
    }
    r->next = NULL;
    return L;
}

//求表的长度
int Length(LinkList L){
    int len = 0;
    LNode *p;
    p = L;
    //不带头结点p!=NULL
    while (p->next != NULL){
        p = p->next;
        len ++;
    }
    return len;
}

//按序查找
LNode *GetElem(LinkList L, int i){
    if (i < 0)
        return NULL;
    LNode *p;
    int j = 0;
    p = L;
    while (p != NULL && j < i){
        p = p->next;
        j ++;
    }
    return p;
}

//按值查找
LNode *LocateElem(LinkList L, int e){
    LNode *p = L->next;
    while (p != NULL && p->data != e){
        p = p->next;
    }
    return p;
}

//后插操作
bool InsertNextNode(LNode *p, int e){
    if (p == NULL)
        return false;
    LNode *s = (LNode*)malloc(sizeof(LNode));
    if (s == NULL)
        return false;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

//前插操作
bool InsertPriorNode(LNode *p, int e){
    if (p == NULL)
        return false;
    LNode *s = (LNode*)malloc(sizeof(LNode));
    if (s == NULL)
        return false;
    s->next = p->next;
    p->next = s;
    s->data = p->data;
    p->data = e;
    return true;
}

//按位序插入(带头结点)
bool ListInsert(LinkList &L, int i, int e){
    if (i < 1)
        return false;
    LNode *p = GetElem(L,i - 1);
    return InsertNextNode(p,e);
}

/*

//按位序插入(不带头结点)
bool ListInsert(LinkList &L, int i, int e){
    if (i < 1)
        return false;
    if (i == 1){
        LNode *s = (LNode*)malloc(sizeof(LNode));
        s->data = e;
        s->next = L;//此时L=NULL
        L = s;//头指针指向新结点
        return true;
    }
    LNode *p;
    int j = 1;//当前p指向第几个结点
    p = L;//p指向第一个结点(注意:非头结点)
    while (p != NULL && j < i - 1){
        p = p->next;
        j ++;
    }    
    //LNode *p = GetElem(L,i - 1);
    return InsertNextNode(p,e);
}

*/

//按位序删除(带头结点)
bool ListDelete(LinkList &L, int i, int &e){
    if (i < 1)
        return false;
    LNode *p = GetElem(L,i - 1);
    if (p == NULL)
        return false;
    LNode *q = p->next;
    e = q->data;
    p->next = q->next;
    free(q);
    return true;
}

//删除指定结点
bool DeleteNode(LNode *p){
    if (p == NULL)
        return false;
    LNode *q = p->next;//令q指向p的后继结点
    p->data = p->next->data;//和后继结点交换数据域
    p->next = q->next;//将q结点从链中断开
    free(q);//释放后继节点
    return true;
}

//打印链表
void PrintList(LinkList L){
    LNode *p = L->next;
    while (p != NULL){
        cout << p->data <<' ';
        p = p->next;
    }
    cout << endl;
}

int main()
{
    cout << "-------TestTailInsert-------" << endl;
    LinkList L;
    InitList(L);
    List_TailInsert(L);
    PrintList(L);
    cout << Length(L) << endl;
    
    cout << "-------TestInsert-------" << endl;
    ListInsert(L,1,2);
    PrintList(L);
    cout << Length(L) << endl;
    
    ListInsert(L,2,16);
    PrintList(L);
    cout << Length(L) << endl;

    cout << "-------TestSerch-------" << endl;    
    cout << GetElem(L,2)->data << endl;
    cout << LocateElem(L,16)->data << endl;
    
    cout << "-------TestDelete-------" << endl;
    int e = 0;//暂时保存被删除数值
    ListDelete(L,1,e);
    ListDelete(L,1,e);
    PrintList(L);
    cout << Length(L) << endl;
    
    cout << "-------TestPriorInsert-------" << endl;
    LinkList K;
    InitList(K);
    List_HeadInsert(K);
    PrintList(K);
    return 0;
}

/*

6 5 5 3 6 9999
6 5 5 3 6 9999

*/
posted @ 2021-07-19 22:47  Treasure_lee  阅读(290)  评论(0编辑  收藏  举报