数据结构(C++)学习篇(三):线性表(链式表示和实现)

目录

链式存储结构

单链表

2.存储结构

3.定义

4.初始化单链表

5.判断链表是否为空

6.销毁

7.清空链表(链表存在但是没有元素)

8.求表长

9.获取元素(取第i个元素的值)

10.按值查找

10.1根据指定数据获取该数据所在的位置

10.2根据指定数据获取该数据的位置序号

11.插入

12.删除

13.建立单链表

13.1头插法

13.2尾插法


链式存储结构

  • 线性表中数据元素(结点)在存储器中的位置是任意的,即:逻辑上相邻,物理位置不一定相邻
  • 结点
  • 链表   n个结点由指针链组成的一个链表

单链表

1.带头结点的单链表

非空表                                                                                               空表

          

2.存储结构

3.定义
#define TRUE      (1)
#define FALSE     (0)
#define OK        (1)
#define ERROR      (0)
#define INFEASIBLE (-1)
#define OVERFLOW   (-2)

typedef char ElemType;
typedef int Status;

typedef struct Lnode{
    ElemType data;        //数据域
    struct Lnode *next;   //指针域
}LNode, *LinkList;

LinkList L; //定义链表L
//LNode *p;   //定义结点指针  等价于 LinkList p(一般不用);
4.初始化单链表
Status InitList_L(LinkList &L)

{
    L = new LNode;   // c语言:L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;
    return OK;
}
5.判断链表是否为空
//空表:链表中无元素,但是头指针和头结点还在

int ListEmpty(LinkList L) //空表返回1,否则返回0
{
    if(L->next != NULL)
        return 0;
    else
        return 1;
}
6.销毁
//从头指针开始,依次释放所有结点
Status DestroyList(LinkList &L)
{
    LNode *p = NULL;
    while(L != NULL)
    {
        p = L;
        L = L->next;
        delete p;
    }
    return OK;
}
7.清空链表(链表存在但是没有元素)
//将L重置为空表
Status ClearList(LinkList &L) 
{
    LNode *p=NULL, *q=NULL;
    p = L->next;
    while(p!=NULL)  //没到表尾
    {
        q = p->next;
        delete p;
        p = q;
    }
    L->next = NULL;    //头结点指针域为空
    return OK;
}
8.求表长
int ListLength_L(LinkList L)
{
    LinkList p = L->next;  //p指向第一个结点
    int index = 0;

    while(p != NULL)  //遍历统计结点个数
    {
        index++;
        p = p->next;
    }
    return index;
}
9.获取元素(取第i个元素的值)
//获取线性表L中的某个元素的内容,通过变量e返回
Status GetElem_L(LinkList L, int i, ElemType &e)
{
    LNode *p = L->next;
    int j = 1;

    while(p && j<i)
    {
        p = p->next; 
        ++j;
    } 

    if(!p || j>i) //第i个元素不存在
        return ERROR;

    e = p->data;
    return OK;
}
10.按值查找

时间复杂度:O(n)

10.1根据指定数据获取该数据所在的位置
//return: 成功返回e元素的地址,失败返回NULL;
LNode *LocateElem(LinkList L, ElemType e)
{
    LNode *p = L->next;
    while(p && p->data != e){
        p = p->next;
    }
    return p;
}
10.2根据指定数据获取该数据的位置序号
//return: 成功返回e元素的位置序号,失败返回0;
LNode *LocateElem(LinkList L, ElemType e)
{
    LNode *p = L->next;
    int j = 1;

    while(p && p->data != e){
        p = p->next;
        j++;
    }

    if(p != NULL) 
        return j;
    else
        return 0;
}
11.插入
//在第i个结点前插入值为e的新结点
Status ListInsert_L(LinkList &L, int i, ElemType e)
{
    LNode *p = L;
    int j = 0;
    while(p && j<i-1)//寻找第i-1个结点
    {    
        p = p->next;
        ++j;
    }
    if(!p || j>i-1) //非法判断
        return ERROR;

    s = new LNode; //生成新结点
    s->data = e;

    s->next = p->next; //将新结点插入到L中
    p->next = s;
    return OK;
}
12.删除
//将L中第i个数据元素删除
Status ListDelete_L(LinkList &L, int i, ElemType &e)
{
    LNode *p = L;
    int j = 0;
    
    while(p->next && j<i-1){    //找到第i个结点,p指向其前驱
        p=p->next;
        ++j;
    }
    if(!(p->next) || j>i-1) 
        return ERROR;

    q=p->next;            //临时保存被删结点的地址用于释放
    p->next = q->next;
    e=q->data;         //保存删除结点的数据域
    delete q;
    return OK;
}
13.建立单链表
13.1头插法
//头插法建立一个链表,直接实用性不大 ,时间复杂度: O(n)
void CreateList_H(LinkList &L, int n)
{
    L = new LNode;
    L->next = NULL;

    for(int i=n; i>0; --i)
    {
        p = new LNode;
        cin >> p->data;    //手动输入
        p->next = L->next;
        L->next = p;
    }
}        
13.2尾插法
//正位序输入n个元素的值,建立带头结点的单链表L,时间复杂度:O(n),直接实用性不大
void CreateList_R(LinkList &L, int n)
{
    L = new LNode;
    L->next = NULL;
    LNode *r = L;
    
    for(int i=0; i<n; ++i){
        p = new LNode;
        cin >> p->data;
        p->next = NULL;
        r->next = p;
        r=p;
    }
}

=========================================================================

视频:戳这里_B站大学

推荐相关文章:数据结构(C++)学习篇(二):线性表(顺序表示和实现)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值