• 线性结构--链表


    什么是数据结构

    数据结构是数据对象,以及存在于该对象的实例和 组成实例的数据元素之间的各种联系。

    数据结构是ADT(抽象数据类型Abstract Data Type)的物理实现。

    数据结构(data structure)是计算机中存储、组织 数据的方式。通常情况下,精心选择的数据结构可以 带来最优效率的算法。

    • 解决问题方法的效率,跟数据的组织方式有关

    • 解决问题方法的效率,跟空间的利用效率有关有关

    • 解决问题方法的效率,跟算法的巧妙程度有关

    • 数据对象在计算机中的组织方式

      • 逻辑结构
      • 物理存储结构
    • 抽象数据类型(Abstract Data Type)

      • 数据类型

      • 数据对象集 

      • 数据集合相关联的操作集

    ​ 抽象:描述数据类型的方法不依赖于具体实现 :与存放数据的机器无关 ,与数据存储的物理结构无关 ,与实现操作的算法和编程语言均无关
    只描述数据对象集和相关操作集“是什么”,并不涉及 “如何做到”的问题

    什么是算法

    • 算法
    1. 一个有限的指令集

    2. 接收一些输入(有限情况下不用输入)

    3. 产生输出

    4. 一定在有限步骤之后终止

    5. 每一条指令必须 :有充分明确的目标,不可以有歧义 ;计算机能处理的范围之内 ;描述应不依赖于任何一种计算机语言以及具体的实现 手段

    什么是好的算法

    • 空间复杂度S(n)——根据算法写成的程序在执行时 占用存储单元的长度。这个长度往往与输入数据的 规模有关。空间复杂度过高的算法可能导致使用的 内存超限,造成程序非正常中断。

    • 时间复杂度T(n)——根据算法写成的程序在执行时 耗费时间的长度。这个长度往往也与输入数据的规 模有关。时间复杂度过高的低效算法可能导致我们 在有生之年都等不到运行结果。

    • 复杂度的线性表示法

    T(n) = O(f(n))表示存在常数C >0, n0>0 使得当 n>=n0时有T(n) <= C·f(n)

    T(n) = Ω(g(n))表示存在常数C >0, n0>0 使得当 n >= n0时有T(n) >= C·g(n)

    T(n) = Θ(h(n))表示同时有T(n) = O(h(n))和 T(n) = Ω(h(n))

    应用实例

    • 求最大子列和
    // 给定N个整数的序列{ A1, A2, …, AN}, 求函数的最大值
    /**************************
     *	参数一: 子列数组       *
     *  参数二: 子列元素个数    *
    **************************/
    int MaxSubseqSum1(int A[], int N)
    {
    	int ThisSum, MaxSum;
    	int i, j, k;
    	// i是子列左端位置
    	for (int i = 0; i < N; i++)
    	{
    		// j是子列右端位置
    		for (int j = i; j < N; j++) {
    			ThisSum = 0;    // 表示从A[i] 到A[j]的子列和
    			for (int k = i; k <= j; k++)
    				ThisSum += A[k];
    			if (ThisSum > MaxSum)    // 如果得到这个子列和更大
    				MaxSum = ThisSum;    // 就更新结果
    		}
    	}
    	return MaxSum;
    }
    
    // 方法二
    int MaxSubseqSum(int A[], int N)
    {
    	int ThisSum, MaxSum;
    	int i, j, k;
    	// i是子列左端位置
    	for (int i = 0; i < N; i++)
    	{
    		ThisSum = 0;    // 表示从A[i] 到A[j]的子列和
    		// j是子列右端位置
    		for (int j = i; j < N; j++) {
    			
    			ThisSum += A[j];   // 对于相同的i 不同的j 在j-1次循环上加一项即可
    			if (ThisSum > MaxSum)    // 如果得到这个子列和更大
    				MaxSum = ThisSum;    // 就更新结果
    		}
    	}
    	return MaxSum;
    }
    

    线性结构

    什么是线性表

    • 线性表(Linear List)是同类型元素构成有序序列的线性结构
    1. 表中的元素个数称为线性表的长度
    2. 线性表没有元素时称为空表
    3. 表的起始位置称为表头,表的结束位置称表尾

    线性表的顺序存储实现

    • 线性存储
    // 定义一个线性表
    typedef struct LNode *List;
    typedef int Position;
    typedef int ElementType;
    
    // 通过数组的连续存储空间顺序存放线性表的各元素
    struct LNode {
    	ElementType Data[MAXSIZE];
    	int Last;
    };
    
    struct LNode L;
    
    // 线性表的初始化
    List MakeEmpty()
    {
    	List Ptrl;
    	Ptrl = (List)malloc(sizeof(struct LNode));
    	Ptrl->Last = -1;
    	return Ptrl;
     }
    
    // 查找
    #define ERROR -1
    
    Position find(int i, ElementType X)
    {
    	Position i = 0;
    	while (i < L.Last && L.Data[i] != X)
    	{
    		i++;
    	}
    	if (i > L.Last) return ERROR;
    	else  return i;    //在表外返回错误
    	
    }
    
    // 插入
    bool Insert(List L, ElementType X, Position P)
    {
    	// 检查空间是否已满
    	if (P = MAXSIZE - 1)
    	{
    		printf("空间已满
    ");
    		return false;
    	}
    
    	// 检查位置是否合法
    	if (P > L->Last || P < 0)
    	{
    		printf("位置不合法
    ");
    		return false;
    	}
    	for (int i = L->Last; i >= P; i--)
    	{
    		// 将位置p及以后的元素顺序向后移动
    		L->Data[i + 1] = L->Data[i];
    	}
    		L->Data[P] = X;   // 新的元素插入
    		L->Last++;
    		return true;
    }
    
    // 删除
    bool Delete(List L, ElementType X, Position P)
    {
    	// 检查位置是否合法
    	// 检查位置是否合法
    	if (P > L->Last || P < 0)
    	{
    		printf("没有该元素
    ");
    		return false;
    	}
    	// 位置P的后一个元素向前移动
    	for (int i = P+1; i <= L->Last; i++)
    	{
    		L->Data[i-1] = L->Data[i];
    	}
    	// 总长度 - 1;
    	L->Last--;
    	return true;
    }
    
    
    • 链式存储
    /*******************
    *				   *
    *  链式存储实现      *
    *				   *
    ********************/
    
    
    // 不需要逻辑上相邻的连个元素物理上也相邻
    // 通过链来建立起数据元素之间的逻辑关系
    
    // 定义一个线性表
    //typedef struct LNode* ptrToLNode;
    typedef int ElementType;
    
    // 通过数组的连续存储空间顺序存放线性表的各元素
    struct LNode {
    	ElementType Data;   // 节点代表的数据
    	LNode* Next;        // 指向下一个节点的位置
    };
    
    typedef LNode* Position;
    typedef LNode* List;
    
    #define ERROR NULL
    
    // 求表长
    int Length(List Ptr)
    {
    	int j = 0;
    	while (Ptr)
    	{
    		Ptr = Ptr->Next;
    		j++;
    	}
    	return j;
    }
    
    // 查找
    Position Find(List L, ElementType X)
    {
    	Position p = L;    // P指向L的第一个节点
    	while (p && p->Data != X)
    		p = p->Next;
    	if (p)
    		return p;
    	else
    		return ERROR;
    }
    
    // 插入
    bool Insert(List L, ElementType X, Position p)
    {
    	Position tem, pre;
    	// 查找p的前一个节点
    	for (pre = L; pre && pre->Next != p; pre = pre->Next);
    	
    	// 位置检查
    	if (pre = NULL)
    	{
    		printf("插入的位置有误
    ");
    		return false;
    	}
    	else
    	{
    		tem = (Position)malloc(sizeof(struct LNode));
    		tem->Data = X;
    		tem->Next = p;
    		pre->Next = tem;
    		return true;
    	}
    }
    
    // 带头节点的删除
    bool Delete(List L, Position p)
    {
    	Position tmp, pre;
    	for (pre = NULL; pre && pre->Next != p; pre = pre->Next);
    	
    	if (pre == NULL || p == NULL)   // p所指的节点不在L中
    	{
    		printf("删除的的位置有误
    ");
    		return false;
    	}
    	else
    	{
    		// 找到了p的前一个节点
    		// 将p的节点删除
    		pre->Next = p->Next;
    		free(p);
    		return true;
    	}
    }
    

    广义表

    • 广义表是链式表的推广
    • 对于线性表而言,n个元素都是基本的单元素
    • 广义表中,这些元素不仅可以是单元素也可以是另一个广义表

    多重链表

    • 多重链表:链表中的节点可以隶属于多个连

    多重链表中的节点的指针域会有多个,但是包含两个指针域的链表不一定是多重链表,例如双线链表

    • 用途

    如树、图这种相对复杂的数据结构都可以使用多重链表的方式实现存储

  • 相关阅读:
    hash介绍
    序列化
    面向对象编程
    计算机系统基础知识05
    19、Python之队列
    18、Python之多线程
    17、Python之paramikomo
    16、Python之socket网络编程
    15、Python之异常处理
    14、Python之反射
  • 原文地址:https://www.cnblogs.com/TJTO/p/12435984.html
Copyright © 2020-2023  润新知