数据结构与算法笔记——线性表基本实现

目录

前言

一、线性表的定义是什么?

二、线性表的特点是什么?

三、线性表的基本操作有哪些?

四、线性表的分类(按照存储结构分)

1.顺序表

2.链表

(1)单链表

(2)双链表

(3)循环链表

(4)静态链表

总结


 

 


前言

大体介绍一下数据结构的知识点,便于个人复习记忆


一、线性表的定义是什么?

线性表示n个数据元素的有限序列;
在复杂的线性表(即每个数据元素都含有若干数据项)中,数据元素被称为记录,含有大量记录的此线性表则被又称为文件。

二、线性表的特点是什么?

除第一个元素外,其余元素都只有一个前驱节点;
除最后一个外,其余元素都仅有一个后继节点。
反隐了节点间一对一的关系

三、线性表的基本操作有哪些?

1.创建表InitList(List &L)

2.销毁DestroyList(List &L)

3.重置为空表ClearList(List &L)

4.判断表是否非空ListEmpty(List L)

5.计算表的长度ListLength(List L)

6.添加InsertList(List &L, int i, Data e)

7.删除DeleteList(List &L, int i, Data &e)

8.修改

9.查找

按位查找GetElem(List L, int i, Data &e)
按值查找LocateElem(List L, Data e,compare())

10.线性表的合并

四、线性表的分类(按照存储结构分)

1.顺序表

定义:
线性表的顺序实现,即逻辑上相邻的元素在计算机物理存储单元上也是相邻的

特点:
存储密度小,需要占据一块连续的存储空间
便于随机访问,查找效率快
不便于添加、删除操作

实现和初始化:
(1)静态分配

#define  List_Size  100

struct Data{
  int a;
  double b;
};

typedef struct LNode{
  Data   s[List_Size];    //静态分配是以固定长度的数组来存储数据元素
  int    length;
}List; 

bool InitList(List &L){
   L.length = 0;
   return true;
}

2)动态分配

#define  List_Size  100

struct Data{
  int a;
  double b;
};

typedef struct LNode{
  Data   *s;    //静态分配是以固定长度的数组来存储数据元素
  int    length;
  int    ListSize;
}List, *LinkList; 

bool InitList(List &L){
   L.s = (LinkList )malloc(List_Size*sizeof(Data));
   if(L.s)  return false;
   
   L.length = 0;
   L.ListSize = List_Sizel
   return true;
}

由于动态分配易于扩展存储内存,因此常用动态分配来实现顺序表。

插入:

bool InsertList(List &L, int i, Data e){
   if( i < 1 || i > length + 1) return false;

   Data  *p = &L.s[i-1];
   Data  *q = &L.s[L.length];
   
   for (; q > p; q--)    //必须从后面超前面右移
      *q = *(q-1); 
      
   *p = e;
   L.length++;
   return true;
}

删除:

bool DeleteList(List &L, int i, Data &e){
    if ( i < 1 || i > L.length)   return false;

   Data *p = &L.s[i-1];
   Data *q = &L.s[length-1];
   e = *p;
   
   for(; p < q; p++)
      *p = *(p+1);
   L.length--;
   return  true; 
}

查找:

//按位查找
bool GetElem(List L, int i, Data &e){
    if ( i < 1 || i > length) return false;

    e = L.s[i-1];

    return true;
}

//按值查找
 bool compare(Data x, Data y){
   if(x.a == y.a)
     return true;
   else
     return false;
 }

bool LocateElem(List L,int &n, Data e){
   for(int j = 0; j < L.length; j++)
     if(compare(L.s[j-1],e)){
        n = j+1;
        return true;
   }
   return false;
}

2.链表

(1)单链表

初始化建立单链表:

struct Data{
   int a;
   double b;
};

typedef struct LNode{
  Data  x;
  struct LNode *next;
}List,*LinkList;

//逆序插入多个数据,建立带头结点的单链表
bool InitList(LinkList &L,int n){
  L = (LNode *)malloc(sizeof(LNode));
  if(L) return false;
  L->next = NULL;

  for(; n > 0; n-- ){
  LinkList p = (LinkList )malloc(sizeof(LNode));
  if(p)  return false;
  //输入节点数据
  scanf("%d,%f",p->x.a, p->x.b);
  
  p->next = L->next;
  L->next = p;
  }
  
  return true;
}

//逆序插入多个数据,建立不带头结点的单链表
bool InitList(LinkList &L, int n){
   L = NULL;

for(; n > 0; n--){
   LinkList p = (LinkList )malloc(sizeof(LNode));
   if(p) return false;
   //输入节点数据
  scanf("%d,%f",p->x.a, p->x.b);

  p->next = L;
  L = p;
  }
  return true;
}  

插入节点

//按位插入节点
bool InsertList(LinkList &L, int i, Data e){
 if (i < 1)
   return false;
 
 LinkList p = L;
 int j = 0;

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

 LinkList s = (LinkList )malloc(sizeof(LNode));
 if(s) return false;
 s.x = e;

 s->next = p->next;
 p->next = s;

 return true;
}
 
//指定节点前插法(节点实际还是后插,只是将数据调换)
bool PriorElem(LinkList &p, Data e){
  LinkList q = (LinkList )malloc(sizeof(LNode));
  if(q) return false;
  
  q->next = p->next;
  p->next = q;
  q.x = p.x;
  p.x = e;

 return true;
}

//指定节点后插法
bool NextElem(LinkList &p, Data e){
  LinkList q = (LinkList )malloc(sizeof(LNode));
  if(q) return false;
  
  q->next = p->next;
  p->next = q;
  q.x = e;
  
  return true;
}

删除节点:

bool InsertList(LinkList &L, int i, Data &e){
  if( i < 1 ) return false;

  LinkList p = L;
  int j = 0;

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

  p->next = p->next->next;
  return true;
}

(2)双链表

struct Data{
  int a;
  double b;
};

typedef struct LNode{
   Data x;
   struct LNode *prior,*next;
}List,*LinkList;

//

(3)循环链表

(4)静态链表

静态链表的每个节点都是存储游标,而非下一个节点的指针。

#define List_Size 100
struct Data{
 int a;
 double b;
};

typedef struct LNode{
  Data  x;
  int   next;   //节点的游标
}List[List_Size];

bool InitList(List &p, int n){
  p[0].next = 0;
  int tail = 0;  //最尾部节点的位置
  for(int i = 1; i <= n; i++){
     Data m;
     int k;
     scanf("节点数据输入:%d %f", m.a, m.b);
     
     
       

     
  
}

总结

仅是对线性表结构实现汇总,具体分析后续记录

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值