链表入门基础

目录

一、线性表的抽象数据类型描述

1、类型名称:

2、数据对象集:

3、操作集:

4、线性比表的基本操作有:

二、简单链表基础操作

1、求表长

2、查找

3、插入操作的实现

4、删除操作的实现

二、广义表

1、举个例子

2、广义表的定义

三、多重链表

1、多重链表的定义

 2、举个例子


一、线性表的抽象数据类型描述

1、类型名称:

线性表(List)

2、数据对象集:

线性表是n(>=0)个元素构成的有序序列

3、操作集:

线性表L\epsilonList,整数i表示位置,元素x\epsilonElementType

4、线性比表的基本操作有:

(1)、List MakeEmpty():        初始化一个空的线性表L

  (2)、ElementType FindKth(int K, List L):    根据位序K,返回相应的元素   

  (3)、int  Find(ElementType X, List L):        在线性表L中查找X的第一次出现的位置

  (4)、void insert(ElementType X, int  i, List L):        在位置 i 前插入一个新元素X

  (5)、void Delete(int i, List L):        删除指定位序 i 的元素

  (6)、int Length(List L):        返回线性表的长度n

顺序存储结构

//这里是用数组来进行线性表的表示!!!

//初始化(建立空的顺序表)
List MakeEmpty()
{    
    List PtrL;
    PtrL=(List)malloc(sizeof(struct LNode));
    PtrL->Last=-1;
    return PtrL;

}

//查找
int Find(ElenmentType X,List PtrL)
{
    int i=0;
    while(i <= PtrL->Last && PtrL->Data[i]!=X )
          i++;
    if(i >PtrL->Last) return -1;    /*如果没有找到,返回-1*/
    else return i;    /*如果找到了,返回的就是存储位置*/ 

}

//插入(先移动后插入)
void Insert(ElementType X,int i,List PtrL)
{
    int j;
    if(PtrL->Last == MAXSIAE-1){    //表空间已经满了就不可以再插入了,如果是用链表来表示线性表
        printf("表满");                //就不用判断满没满
        return;
    if(i<1 || i>PtrL->Last+2){
         printf("位置不合法");   
         return;
    }
    for(j=PtrL->Last ; j>=i ; j--){    //如果符合插入条件,就需要把插入位置后的元素全部后移
        PtrL->Data[j+1]=PtrL->Data[j];    //进行移动
    }
    PtrL->Data[i-1]=X;    //把X进行插入
    PtrL->Last++;    //Last指向最后一个元素
    return ;
}

//删除(操作顺序和插入相反)
void Delete(int i;List PtrL)
{
    int j;
    if(i<1 || i>PtrL->Last+1){    //检查删除位置的合法性
        printf("不存在第%d个元素",i);
        return ;

    }
    for(j=i ; j<=PtrL->Last ; j++){
         PtrL->Data[j-1]=PtrL->Data[j];   //将要删除后的元素向前移动
    }
    PtrL->Last--;    //Last仍然指向最后的元素
    return ;
}

插入(第 i (1<= i <=n+1)个位置前插入一个值为X的新元素)

下标

    i

01......i-1......n-1......MAXSIZE-1
Dataa1a2......ai......an(Last指向的地方)......        --

先移动后插入:

下标

    i

01......iin-1......nMAXSIZE-1
Dataa1a2......aia n-1......     an(现在Last指向的位置)           --

二、简单链表基础操作

1、求表长

int Length(List PtrL)
{
    List p=PtrL;        //p指向第一个结点
    int i=0; 
    while(p){
        p=p->Next;
        i++;            //当前p指向的是第i个结点
    }
    return i;
}

2、查找

(1)、按照序号查找FindKth

List FindKth(int K,List PtrL)
{
    List p=PtrL;
    int i=1;
    while(p!=NULL && i<K){
        p=p->Next;
        i++;
    }
    if(i==K)
    {
        return p;        //找到第K个,然后返回指针
    }else{
        return NULL;     //否则返回空
    }

}

 (2)、按照值查找Find

List Find(ElementType X,List PtrL){
    List p=PtrL;
    while(p!=NULL && p->Data!=X){
        p=p->Next;
    }
    return p;
}

3、插入操作的实现

List Insert(Element X,int i,List PtrL){
    List p=PtrL;     
    if(i==1){                                  //新结点插入在表头
        s=(List)malloc(size(struct LNode));    //申请、填装新结点
        s->Data=X;
        s->Next=PtrL;
        return s;                             //返回新表头指针
    }
    p=FindKth(i-1,PtrL);                      //查找第i-1个结点
    if(p=NULL){                               //第i-1个结点不存在,所以不可以插入
        printf("参考i错");
        return NULL;
    }else{
        s=(List)malloc(sizeof(struct LNode));  //申请、填装结点
        s->Data=X;
        s->Next=p->Next;                        //新添加的结点在i-1后面
        p->Next=s;
        return PtrL;

    }

}

4、删除操作的实现

List Delete(int i,List PtrL)
{
    List p,s;

    if(i==1) {               //如果要删除第一个结点
        s=PtrL;              //s指向第一个结点
        if(PtrL!=NULL){
            PtrL=PtrL->Next;    //从链表中删除
        }else{
            return NULL;
        }
        free(s);                //释放被删除的结点
        return PtrL;
    }
    p=FindKth(i-1,PtrL)
    if(p==NULL){
        printf("第%d个结点不存在",i-1);
        return NULL;
    }else if(p->Next==NULL){
        printf("第%d个结点不存在",i);
        return NULL;
    }else{
        s=p->Next;            //s指向第i个结点
        p->Next=s->Next;        //从列表中删除
        free(s);                //释放被删除的结点
        return PtrL;
    }
}

二、广义表

1、举个例子

用链表表示二元多项式P(x,y)=9x^^{12}y^2+4x^^{12}+15x^8y^3-x^8y+3x^2

解析:可以将上面的二元多项式看成是关于x的一元多项式(有点了类似换元法)

        P(x,y)=(9y^2+4)x^^{12}+(15y^3-y)x^8+3x^2

及为:ax^^{12}+bx^8+cx^2

二元多项式可以用“复杂”的链表来表示

2、广义表的定义

(1)、广义表是线性表的推广;

(2)、对于线性表而言,n个元素都是基本的单元素;
(3)、广义表中,这些元素不仅可以是单元素也可以是另一个广义表。

typedef struct GNode*GList;
struct GNode{
    int Tag;    //标志域:0表示结点是单元素,1表示结点是广义表
    union{        //子表指针域Sublist与单元素数据域Data复用,即共用存储空间
        ElementType Data;
        GList SubList;
    }URegion;
    GList Next;    //指向后继结点
};

这个域可能是不能分解的单元,也可能是一个指针

三、多重链表

1、多重链表的定义

(1)、多重链表:链表中的结点可能同时隶属于多个链表

(2)、多重链表中的结点的指针域会有多个,如广义表中的Next和SubList两个指针域
(3)、但是包含的两个指针域的链表并不一定是多重链表,可能是双向链表而不是多重链表,所以两个指针域\neq多重链表。

(4)、多重链表用途广泛:基本上如树、图这样相对复杂的数据结构都可以采用多重链表方式进行存储。

 2、举个例子

用多重链表表示矩阵

解析:一般看到矩阵我们都会想到用二维数组来进行表示,但是数组是有缺陷的:数组的大小是事先确定的;对于“稀疏矩阵”,将造成大量的存储空间浪费。所以我们现在采取一种典型的多重链表——十字链表

十字链表的具体操作:

(1)、只存储矩阵中非0的元素项;

(2)、结点的数据域:行坐标Row、列坐标Col、数值Value

(3)、每个结点通过两个指针域,把同行、同列串起来

行指针(或者称为向右指针)Right

列指针(或者称为向下指针):Down

(4)、用一个Tag来区分头结点和非0元素结点

(5)、头节点的标识值为“Head”,矩阵非0元素结点的标识值为“Term”

 

 

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值