当前位置: 首页 > ds >正文

数据结构基础内容(第二篇:线性结构)

# 线性结构

一元多项式

f(x) = a0 + a1x+...+anx

方法一:顺序存储结构直接表示  

a[i]: 系数  

方法二:顺序存储表示非零项  

用结构数组表示:系数与指数的二元组  

方法三:链表结构存储非零项  

coef expon link;  

```c

typedef struct PolyNode *polynomial;

truct PolyNode{

   int coef;

   int expon;

   polynomial link;

}

```

## 线性表 Linear List

同类型数据元素构成有序序列的线性结构。  

数据对象集:n个元素构成的有序序列  

操作集:线性表L属于List, 整数表示位置,元素x属于ElementType。操作:

* List MakeEmpty(): 初始化一个空表

* ElementType FindKth(int K, List L); 根据位序K,返回相应元素

* int Find(ElementType x, List L);  在表中查找X第一次出现的位置

* void insert(ElementType X, int i, List L); 插入

* void Delete(int i, List l);  删除  

* int length(List L); 返回长度  

## 线性存储序列的实现

```c

typedef struct LNode *List;

struct LNode{

   ElementType Data[MAXSIZE];

   int Last;

};

struct LNode L;

List PtrL;

```

访问元素:L.Data[i] or PtrL->Data[i]  

线性表的长度:L.Last+1 或 PtrL->Last+1  (last代表位置,因为从零开始所以是n-1)

* 初始化  

```c

List MakeEmpty( )

{

   List PtrL;

   PtrL = (List )malloc( sizeof(struct LNode) );  

   PtrL->Last = -1; //last若为0 则表示表里有一个元素在0号位置

   return PtrL;

}

```

* 查找  

```c

int Find( ElementType 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; /* 找到后返回的是存储位置 */ }

}

```

平均查找次数(n +1)/2,平均时间性能为 O(n)  

* 插入  

第 i (1≤i≤n+1)个位置上插入一个值为X的新元素(其实是插在数组的第i-1个位置,因为数组从0开始标)先移动再插入,n挪到n+1,n-1挪到n, ...,i-1挪到i  

在链表L中的第一个位置插入元素X,如下,MAXSIZE代表链表的size

```c

void Insert( ElementType X, int i, List PtrL ) {

   int j;

   /* 表空间已满,不能插入*/

   if ( PtrL->Last == MAXSIZE-1 )

   {

      printf("表满");

      return;

   }

   /*检查插入位置的合法性*/

   if ( i < 1 || i > PtrL->Last+2)

   {

      printf("位置不合法");

      return;

   }

   /* 开始挪位子,从最后的一位last开始直到i-1 */

   for ( j = PtrL->Last; j >= i-1; j-- )

      PtrL->Data[j+1] = PtrL->Data[j];

   

   PtrL->Data[i-1] = X; /*新元素插入*/

   PtrL->Last++; /*Last仍指向最后元素*/

   return;

}

```

平均移动次数为 n /2,  

/*检查插入位置的合法性*/ 平均时间性能为 O(n)  


* 删除  

删除第i个位置上的元素,i在1到n之间,对应数组下表0到n-1  

删掉下表为i-1的元素,下标i的元素挪到i-1...

```c

void Delete( int i, List PtrL )

{

   intj;

   /*检查空表及删除位置的合法性*/

   if( i < 1 || i > PtrL->Last+1 )

   {

   printf (“不存在第%d个元素”, i );

   return ;

   }

   /*将 ai+1~ an顺序向前移动, 从第i位开始,到last */

   for ( j = i; j <= PtrL->Last; j++ )

      PtrL->Data[j-1] = PtrL->Data[j];

     

   PtrL->Last--; /*Last仍指向最后元素*/

   return;

}

```

平均移动次数为 (n-1) /2  

平均时间性能为 O(n)

## 链式存储的实现  

一个线性表用数组存储的时候,相邻的元素不仅逻辑上不仅逻辑上相邻,物理上也是相邻的。而链表通过链连接,建立数据元素的逻辑关系。

```c

typedef struct LNode *List;

struct LNode

{

   ElementType Data;

   List Next;

};

struct Lnode L;

List PtrL;

```

* 求表长  

用临时指针p指向链表头Ptrl,然后遍历,直到null

```c

int Length ( List PtrL )

{

   List p = PtrL;  /* p指向表的第一个结点*/

   int j=0;

   while ( p )

   {

      p = p->Next;

      j++;  /* 当前p指向的是第 j 个结点*/

   }

   return j;

}

```

* 查找  

1. 按序号查找 根据位序K,返回相应元素 FindKth(int K, List L)

```c

List FindKth( int K, List PtrL )

{

   List p = PtrL;

   int i=1;  // i代表第几给元素。因为一开始p指向第一个元素,所以i=1

   while (p !=NULL && i < K )

   {

      p = p->Next;

      i++;

   }

   if ( i == K ) /* 找到第K个,返回指针 */

      return p;

   else return NULL;  /* 没找到第K个,循环因为 p=NULL 而退出 */

}

```

2. 按值查找:Find(ElementType x, List L)

```c

List Find( ElementType X, List PtrL )

{

   List p = PtrL;

   while ( p!=NULL && p->Data != X ) // 条件1表不空,条件2没找到X,就继续

      p = p->Next;

   return p; //找到了:返回节点p。没找到返回p = NULL

}

```

* 插入  

在第 i-1 (1≤i≤n+1) 个结点后插入一个值为X的新结点  

1. 先构造一个新结点,用s指向; mallo

2. 再找到链表的第 i-1个结点,用p指向;

3. 然后修改指针,插入结点 ( p之后插入新结点是 s)

```c  

   s-> next = p -> next;

   p -> next = s

```

实现

```c

List Insert( ElementType X, int i, List PtrL )

{

   List p, s;

   if ( i == 1 )   /* 新结点插入在表头 */

   {

      s = (List)malloc(sizeof(struct LNode));  /*申请、填装结点s */

      s->Data = X;

      s->Next = PtrL;

      return s;  // s成为新的head,返回出去

   }

   p = FindKth( i-1, PtrL );  /* 查找第i-1个结点 */

   if ( p == NULL )  

   {

      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;

   }

}

```

* 删除  

删除链表的第 i (1≤i≤n) 个位置上的节点  

1. 先找到链表的第 i-1个结点,用p指向;

2. 再用指针s指向要被删除的结点(p的下一个结点);  

3. 然后修改指针,删除s所指结点;  `p->next = s->next`

4. 最后释放s所指结点的空间。

实现

```c

List Delete( int i, List PtrL )

{

   List p, s;

   if ( i == 1 )

   { /* 若要删除的是表的第一个结点 */

      s = PtrL; /*s指向第1个结点*/

      if (PtrL!=NULL)

         PtrL = PtrL->Next; /*从链表中删除*/

      else

         return NULL; // 如果本身就是空链表,return NULL

      free(s);

      return PtrL;

   }

   p = FindKth( i-1, PtrL ); /*查找第i-1个结点*/  

   if ( p == NULL )

   {

      printf(“第%d个结点不存在”, i-1);

   }

   else if ( p->Next == NULL )

   {

      printf(“第%d个结点不存在”, i);

   }else

   {

      s = p->Next;   /*s指向第i个结点*/

      p->Next = s->Next;   /*从链表中删除*/

      free(s);  /*释放被删除结点 */

      return PtrL;

   }

}

```

# 广义表  Generalized List

二元多项式  

可以将上述二元多项式看成关于x 的一元多项式  

矩阵可以用二维数组表示,但二维数组表示有两个缺陷:

1. 一是数组的大小需要事先确定

2. 对于“稀疏矩阵 ”,将造成大量的存储空间浪费。  

采用一种典型的多重链表——十字链表来存储稀疏矩阵

* 只存储矩阵非0元素项 结点的数据域:行坐标Row、列坐标Col、数值Value

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

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

   * 列指针(或称为向下指针)Down  

Term 代表非0项  

特殊Term A 代表4行5列,7个非零项

http://www.xdnf.cn/news/16592.html

相关文章:

  • Qt 分裂布局:QSplitter 使用指南
  • 07.4-使用 use 关键字引入路径
  • python中的容器与自定义容器
  • SpringBoot多容器化实例实战
  • FFmpeg——参数详解
  • 墨者:通过手工解决SQL手工注入漏洞测试(MongoDB数据库)
  • C++学习(线程相关)
  • 负载均衡Haproxy
  • SABR-Net
  • uniapp input 聚焦时键盘弹起滚动到对应的部分
  • iOS安全和逆向系列教程 第21篇:iOS应用加密与混淆技术深度剖析
  • Java面试宝典:MySQL性能优化
  • 用 ESP32 和 LCD 轻松显示植物湿度
  • 第十八章:AI的“通感”:揭秘图、文、音的共同语言——CLIP模型
  • 系统整理Python的循环语句和常用方法
  • Keil MDK 嵌入式开发问题:Error: L6218E: Undefined symbol HAL_TIM_PWM_ConfigChannel
  • GIt学习——分布式版本控制工具
  • 设计模式(八)结构型:桥接模式详解
  • 设计模式(七)结构型:适配器模式详解
  • 【网络协议安全】任务15:DHCP与FTP服务全配置
  • 安装Selenium⾃动化
  • PiscCode使用OpenCV实现漂浮方块特效
  • 三种常用的抗锯齿
  • Java大数据面试实战:Hadoop生态与分布式计算
  • esp32s3创建rust工程 window成功mac
  • 结构化文本文档的内容抽取与版本重构策略
  • net8.0一键创建支持(Orm-Sqlite-MySql-SqlServer)
  • 【最新最完整】SpringAI-1.0.0开发MCP Server,搭建MCP Client 实战笔记(进阶+详细+完整代码)
  • Map(HashMap、LinkedHashMap、TreeMap)双列集合
  • 【机器学习深度学习】LLaMAFactory评估数据与评估参数解析