数据结构:单向链表

1.线性表的链式存储结构

  • 结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻
  • 线性表的链式表示又称为非顺序映像链式映像
  • 用一组物理位置任意的存储单元来存放线性表的数据元素。
  • 这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。
  • 链表中元素的逻辑次序和物理次序不一定相同

1.1与链式存储有关的术语

  1. 结点:数据元素的存储映像。由数据域和指针域两部分组成
    数据域 指针域
  2. 链表:
  • n个结点由指针链组成一个链表。
  • 它是线性表的链式存储映像,称为线性表的链式存储结构

1.2单链表、双链表、循环链表

  • 结点只有一个指针域的链表,称为单链表或线性链表
  • 结点有两个指针域的链表,称为双链表
  • 首尾相接的链表称为循环链表

1.3头指针、头结点和首元结点

  • 头指针:是指向链表中第一个结点的指针
  • 首元结点:是指链表中存储第一个数据元素ā的结点
  • 头结点:是在链表的首元结点之前附设的一个结点:

1.4链表的特点

(1)结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻。
(2)访问时只能通过头指针进入链表,并通过每个结点的指针域依次向后顺序扫描其余结点,所以寻找第一个结点和最后一个结点所花费的时间不等。

2.链表应该如何表示?

typedef  int ElemType;  
typedef struct LNode {      //声明结点的类型和指向结点的指针类型  
    ElemType data;      //结点的数据域  
    struct LNode* next;     //结点的指针域  
}Lnode,*LinkList;
  1. ElemType 的定义
    • ElemType 被定义为 int 类型,这意味着链表节点中的数据域 data 将存储整数类型的数据。
  2. LNode 结构体的定义
    • LNode 结构体包含两个成员:
      • ElemType data:用于存储节点的数据。
      • struct LNode* next:用于指向下一个节点的指针。
  3. LinkList 的定义
    • LinkList 是一个别名,实际上是指向 LNode 结构体的指针类型。这意味着 LinkList 可以用来指向链表的头节点或任何节点。

3.单向链表的一些简单操作

3.1单向链表的初始化

算法步骤
(1)生成新结点作头结点,用头指针L指向头结点。
(2)将头结点的指针域置空。
算法描述

void InitLink(LinkList L) {  
    L = (LinkList)malloc(sizeof(Lnode));  
    L->next = NULL;  
    return true;  
}

3.2单向链表的销毁

算法思路
从头指针开始,依次释放所有结点
算法描述

// 销毁链表  
void DestoryLink(LinkList L) {  
    LinkList p;  
    while (L) {  
        p = L;  
        L = L->next;  
        free(p);  
    }  
}

3.3清空链表

链表仍存在,但链表中无元素,成为空链表(头指针和头结点仍然在
算法思路
依次释放所有结点,并将头结点指针域设置为空
算法描述

//清空链表  
void ClearLink(LinkList L) {  
    LinkList p,q;  
    p = L->next;    // p指向头结点的下一个域  
    while (p) {     // 循环条件是p不为空  
        q = p ->next;   //q指向p的下一个域  
        free(p);    //将p置为空  
        p = q;      // p指向p的下一个域  
    }  
    L->next = NULL;     //将头结点置为空  
}

这个函数接受一个指向链表头结点的指针 L,然后遍历链表,释放每个节点的内存,并将头结点的 next 指针设置为 NULL,从而清空整个链表。

3.4求单链表包场

算法思路
从首元结点开始,依次计数所有结点
算法描述

//求单链表的表长  
int LengthLink(LinkList L) {  
    int count = 0;  
    LinkList p = L->next;  
    while (p) {  
        count++;  
        p = p->next;  
    }  
    return count;  
}

3.5取值——取单链表中第个元素的内容

算法思路
分别取出表中第n个元素
算法描述

// 查找链表中第n个元素  
int FindLink(LinkList L,int n) {  
    LinkList p = L->next;   //p指向第一个元素  
    //p找到的值应该不为空  
    while (n>0 && p) {  
        p = p->next;  
        n--;  
    }  
    //找到了并且p不为空  
    if (n == 0 && p) {  
        return p->data;  
    }  
    else {  
        return -1;  
    }  
}

3.6按值查找

算法思路
根据指定数据获取该数据所在的位置
算法描述

//按值查找  
int FindValLink(LinkList L,int n) {  
    int count = 0;  
    LinkList p = L->next;  
    while (p->data != n && p) {  
        p = p->next;  
        count++;  
    }  
    if (!p) {  
        return -1;  
    }  
    return count;  
}

3.7插入

算法步骤
1、首先找到a-1的存储位置p。
2、生成一个数据域为e的新结点s。
3、插入新结点:①新结点的指针域指向结点a;②结点a;-1的指针域指向新结点
算法描述

void EnterLink(LinkList L,int n,int e) {  
    LinkList p = L;  
    LinkList s = (LinkList)malloc(sizeof(Lnode));  
    s->data = e;  
    while (n > 0 && p) {  
        p = p->next;  
        n--;  
    }  
    if(!p) {  
        printf("找不到相应的位置\n");  
        free(s);    //释放刚刚的内存  
    }  
    s->next = p->next;  
    p->next = s;  
}

3.8删除——删除第个结点

算法步骤
1、首先找到a;-1的存储位置p,保存要删除的a的值。
2、令p->next指向a41。
3、释放结点a的空间。
算法描述

//删除节点  
void DestoryNode(LinkList L,int n) {  
    LinkList p = L;  
    int count = 0;  
    while (count < n - 1 && p) {  
        p = p->next;  
        count++;  
    }  
    if (!p) {  
        printf("找不到指定的元素\n");  
    }  
    p->next = p->next->next;  
}

3.9链表的建立

3.9.1头插法——元素插入在链表头部

算法步骤
1.从一个空表开始,重复读入数据
2.生成新结点,将读入数据存放到新结点的数据域中
3.从最后一个结点开始,依次将各结点插入到链表的前端
算法描述

void EnterAheadLink(LinkList L,ElemType a[],int n) {  
    LinkList s;  
    L = (LinkList)malloc(sizeof(Lnode));  
    L->next = NULL;  
    for (int i = 0; i < n; i++) {  
        s = (LinkList)malloc(sizeof(Lnode));  
        s->data = a[i];  
        s->next = L->next;  
        L->next = s;  
    }  
}

3.9.2 尾插法——元素插入在链表尾部

算法步骤
1.从一个空表L开始,将新结点逐个插入到链表的尾部,尾指针指向链表的尾结点。
2.初始时,同均指向头结点。每读入一个数据元素则申请一个新结点,将新结点插入到尾结点后,指向新结点。
算法描述

void EnterEndLink(LinkList L,int a[],int n) {  
    LinkList s;  
    L = (LinkList)malloc(sizeof(Lnode));  
    LinkList r = L;  
    for (int i = 0; i < n;i++) {  
        s = (LinkList)malloc(sizeof(Lnode));  
        s->data = a[i];  
        r->next = s;  
        r = s;  
    }  
    r->next = NULL;  
}
posted @ 2024-10-13 00:18  写代码的大学生  阅读(17)  评论(0编辑  收藏  举报  来源