数据结构(王卓)

目录

2.5线性表的链式表示和实现

一.线性表的链式表示

1.基本概念

2.组成

3.与链式存储有关的术语

 4.单链表

5.双链表

6.循环链表

 7.头指针,头结点和首元结点

 8.存储结构的两种形式

 9.如何表示空表

 10.链表中设置头结点有什么好处

11.头结点的数据域内装什么

 12.链表(链式存储结构)的特点

 2.5.1单链表的定义和表示

一.带头结点的单链表

1.带头指针的单链表

 2.单链表的存储结构

2.5.2单链表基本操作的实现

一.单链表的初始化(带头结点的单链表)

1.构造一个空表

 二.补充单链表的几个常用简单算法

1.判断链表是否为空

2.单链表的销毁

3.清空链表     

     4.求单链表的表长

5. 取值——取单链表中第i个元素的内容

6.查找——根据指定数据获取该数据所在位置(地址)

  7.插入——在第i个结点前插入值为e的新结点         

8.删除——删除第i个结点

9.单链表的建立:头插法——元素插在链表头部

 10.尾插法


2.5线性表的链式表示和实现

一.线性表的链式表示

1.基本概念

(1)用一组物理欸之任意的储存单元来存放线性表的数据元素

(2)这组储存单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。

(3)链表中的元素的逻辑次序和物理次序不一定相同

2.组成

各结点由两个域组成:

数据域:存储元素数值数据

指针域:存储直接后继结点的存储位置

3.与链式存储有关的术语

(1)结点:数据元素的存储映像。由数据域和指针域两部分组成

(2)链表:n个结点由指针链组成一个链表。

                    他是线性表的链式存储映像,称为线性表的链式存储结构

 4.单链表

结点只有一个指针域的链表,称为单链表或者线性链表

5.双链表

结点有两个指针域的链表,称为双链表

6.循环链表

首尾相接的链表称为循环链表

 7.头指针,头结点和首元结点

头结点:是指向链表中第一个结点的指针

首元结点:是指链表中存储第一个数据元素a1的结点

头结点:是在链表的首元结点之前附设的一个结点

 8.存储结构的两种形式

  • 不带头结点的
  • 带头结点的

 9.如何表示空表

  • 无头结点时,头指针为空时表示空表

  •  有头结点时,当头结点的指针域为空时表示空表

 10.链表中设置头结点有什么好处

(1)便于首元结点的处理

首元结点的地址保存在头结点的指针域中,所以在链表的第一个位置上的操作和其他位置一致,无须进行特殊处理。

(2)便于空表和非空表的统一处理

无论链表是否为空,头指针都是指向头结点的非空指针,因此空表和非空表的处理也就统一了。

11.头结点的数据域内装什么

头结点的数据域可以为空,也可以存放线性表长度等附加信息,但此结点不能计入链表长度值

 12.链表(链式存储结构)的特点

(1)结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻。

(2)访问时只能通过头指针进入链表,并通过每个结点的指针域依次向后顺序扫描其余结点,所以寻找第一个结点和最后一个结点所花费的时间不等。

向后顺序扫描其余结点:这种存取元素的方法被称为顺序存取法

 2.5.1单链表的定义和表示

一.带头结点的单链表

1.带头指针的单链表

单链表是由表头唯一确定,因此单链表可以用头指针的名字来命名若头指针名是L,则把链表称为表L。

 2.单链表的存储结构

typedef struct Lnode{  //声明结点的类型和指向结点的指针类型
  ElemType  data;  //结点的数据域
  struct Lnode *next;  //结点的指针域 嵌套类型的指针
}Lnode,*LinkList;  //LinkList为指向结构体Lnode的指针类型

 

  •  为了统一链表的操作,通常这样定义:
typedef Struct{
  char num[8];
  char name[8];
  int score;
}ElemType;

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

2.5.2单链表基本操作的实现

一.单链表的初始化(带头结点的单链表)

1.构造一个空表

Status lnitList_L(LinkList&L){
  L=new LNode;  //或c语言:L=(LinkList)malloc(sizeof(LNode));
  L->next=NULL;
  return OK;
}

(LinkList&L):typedef struct Lnode{
                  ElemType  data;
                  struct Lnode*next;
               }LNode,*LinkList;

 二.补充单链表的几个常用简单算法

1.判断链表是否为空

int ListEmpty(LinkList L){  //若L为空表,则返回1,否则返回0
  if(L->next) //非空
    return 0;
  else
    return 1;
}

2.单链表的销毁

(1)算法思路:从头结点开始,依次释放所有结点

(2)指针怎样指向下一个结点:L=L->next

Status DestroyList_L(LinkList&L){
  Lnode&p; //或LinkList p;
  while(L){
    p=L;
    L=L->next;
    delete p;
  }
 return OK;
}

3.清空链表     

(1)算法思路:依次释放所有结点,并将头结点指针域设置为空

Status ClearList(LinkList&L){  //将L重置为空表
  Lnode*p,*q;  //或LinkListp,q;
  p=L->next; 
  while(p){   //没有表尾
     q=p->next;
     delete p;
     p=q;
}
L->next=NULL;  //头结点指针域为空
return OK;
}

     4.求单链表的表长

int ListLength_L(LinkList L){
  LNode *p;
  p=->next;
  i=0;
 while(p){
   i++;
   p=p->next;
 }
return i;
}

5. 取值——取单链表中第i个元素的内容

(1)算法思路:从链表的头指针出发,顺着链域next逐个结点往下搜索,直到搜索到第i个结点为止。因此,链表不是随机存取结构。

Status GetElem_(LinkList L,int i,ElemType&e){  
  p=->next;j = 1;  //初始化
  while(p&&j<i){   //向后扫描,直到p指向第i个元素或p为空
    p=p->next;++i;
  }
if(!p||j>i)return ERROR;  //第i个元素不存在
e=p->data;                 //取第i个元素
return OK;
}//GetElem_L

6.查找——根据指定数据获取该数据所在位置(地址)

Lnode*LocateElem_L(LinkList L,Elemtype e){
 //在线表L中查找值为e的数据元素
 //找到,则返回L中值为e的数据元素的地址,查找失败返回null
 p=->next;
 while(p&&p->data!=e)
   p=p->next;
 return p;
}


//在线性表L中查找值为e的数据元素的位置序号
int LocateElem_L(LinkList L,Elemtype e){
//返回L中值为e的数据元素的位置序号,查找失败返回0
 p=L->next;j=1;
 while(p&&p->data!=e)
   {p=p->next;j++;}
 if(p)return j;
 else return 0;
}

  7.插入——在第i个结点前插入值为e的新结点         

//在L中第i个元素之前插入数据元素e
Status Listlnsert_L(LinkList &L,int i,ElemType e){
  p=L;j=0;
  while(p&&j<i-1){p=p->next;++j;}  //寻找第i-1个结点,p指向i-1结点
  if(!p||j>i-1)return ERROR;    //i大于表长+1或者小于1,插入位置非法
  s=new LNode;s->data=e;         //生产新结点s,将结点s的数据域置为e
  s->next=p->next;                //将结点s插入L中
  p->next=s;
  return OK;
}//Listlnsert_L

8.删除——删除第i个结点

//将线性表L中第i个数据元素删除
Status ListDelete_L(LinkList&L,int i,ElemType &e){
  p=L;j=0;
  while(p->next&&j<i-1){p=p->next;++j}  //寻找第i个结点,并令p指向其前趋
  if(!(p->next)||j>i-1)return ERROR;  //删除位置不合理
  q=p->next;                              //临时保存被删结点的地址以备释放
  p->next=q->next;                        //改变删除结点前驱结点的指针域
  e=q->data;                              //保存删除结点的数据域
  delete q;                               //释放删除结点的空间
return OK;
}//ListDelete_L

9.单链表的建立:头插法——元素插在链表头部

void CreateList_H(LinkList &L,int n){
  L=new LNode;
  L->next=NULL;         //先建立一个带头结点的单链表
  for(i=n;i>0;--i){
    p=new LNode;        //生成新结点
    cin>>p->data;       //输入元素值scanf(&p->data);
    p->next=L->next;    //插入到表头
    L->next=p;
   }
}//CreateList_H

 10.尾插法

void CreateList_R(LinkList&L,int n){
  L=new LNode;  L->next=NULL;
  r=L;     //尾指针r指向头结点
  for(i=0;i<n:++i){
     p=new LNode;cin>>p->data;  //生产新结点,输入元素值
     p->next=NULL;
     r->next=p;   //插入到表尾
     r=p;  //r指向新的尾结点
      }
}//CreateList_R

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值