单链表的实现及其基本操作

结点的引入

链表是一种链式存储结构,链式存储结构的特点是用一组任意的存储单元存储数据元素。为了能正确表示数据元素之间的线性关系,需引入结点概念。一个结点表示链表中的一个数据元素,节点中除了储存数据元素的信息, 还必须存放指向下一个节点的的指针(单、双链表的最后一个节点除外,它们存储的是一个空指针NULL)

结点的结构如下图所示:

代码如下:

1 typedef struct node{
2     int data;
3     struct node* pNext;
4 }Node,  *PNode;

注:这里假设结点中储存的是整型 (int) 的数据

单链表由多个结点依次连接而成,我们不难想象出它结构:

我们注意到:在第一个结点的前面多了一个头结点,这是为了处理空表的方便而引入的,它的指针指向链表的第一个结点,而它的data域不存放任何信息。

单链表的基本操作

1.创建链表

 1 PNode createList()
 2 {
 3     int len, value;
 4
 5     PNode pHead = (PNode)(malloc(sizeof(Node)));
 6     PNode pTail = pHead;
 7     pTail->pNext = NULL;
 8
 9     printf("请输入你要的节点个数:");
10     scanf("%d", &len);
11     for(int i=1;i<=len;i++){
12         printf("请输入第%d个节点的值:", i);
13         scanf("%d", &value);
14
15         PNode pNew = (PNode)malloc(sizeof(Node));
16         pNew->data = value;
17         pTail->pNext = pNew;
18         pTail = pNew;
19         pTail->pNext = NULL;
20     }
21
22     return pHead;
23 }

2.遍历链表

void traverse(PNode pHead)
{
    printf("遍历结果为:\n");
    PNode pTra = pHead;
    while(pTra->pNext != NULL)
    {
        printf("%d ", pTra->pNext->data);
        pTra = pTra->pNext;
    }
    printf("\n");
}

3.判断链表是否为空

1 bool isEmpty(PNode pHead)
2 {
3     if(pHead->pNext==NULL)
4       return true;
5     else
6       return false;
7 }

4.链表长度

 1 int length(PNode pHead)
 2 {
 3     int len = 0;
 4     while(pHead->pNext!=NULL){
 5         pHead = pHead->pNext;
 6         len++;
 7     }
 8     return len;
 9
10 }

5.插入结点

 1 bool insert(PNode pHead, int pos, int val)
 2 {
 3     if(pos<1 || pos>length(pHead)){
 4         return false;
 5     }else{
 6         PNode pInsert = pHead;
 7         for(int i=1;i<pos;i++){
 8             pInsert = pInsert->pNext;
 9         }
10
11         PNode pNew = (PNode)malloc(sizeof(Node));
12         pNew->data = val;
13         pNew->pNext = pInsert->pNext;
14         pInsert->pNext = pNew;
15
16         return true;
17     }
18
19 }

6.删除结点

 1 bool del(PNode pHead, int pos)
 2 {
 3     if(pos<1 || pos>length(pHead)){
 4         return false;
 5     }else{
 6         PNode pDel = pHead;
 7         for(int i=1;i<pos;i++){
 8             pDel = pDel->pNext;
 9         }
10
11         if(pos==length(pHead)){
12           free(pDel->pNext);
13           pDel->pNext = NULL;
14         }else{
15             PNode pNext = pDel->pNext->pNext;
16             free(pDel->pNext);
17             pDel->pNext = pNext;
18         }
19
20         return true;
21
22     }
23
24
25 }

7.查找节点

(1)按元素值查找

1 PNode locate(PNode pHead, int value)
2 {
3     PNode p = pHead->pNext;
4     while(p&&p->data!=value){      //NULL 是 0
5         p = p->pNext;
6     }
7     return p;
8 }

(2)按序号查找

1 PNode get(PNode pHead, int k)
2 {
3     PNode p = pHead;
4     for(int i=1;i<=k;i++){
5         p = p->pNext;
6     }
7     return p;
8
9 }

完整代码:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 typedef struct node{
  4     int data;
  5     struct node* pNext;
  6 }Node, *PNode;
  7
  8 PNode createList();
  9 void traverse(PNode pHead);
 10 bool isEmpty(PNode pHead);
 11 int length(PNode pHead);
 12 bool insert(PNode pHead, int pos, int val);
 13 bool del(PNode pHead, int pos);
 14 PNode get(PNode pHead, int k); //按序号查找
 15 PNode locate(PNode pHead, int value);//按值查找
 16
 17 int main(void)
 18 {
 19    //test
 20
 21    return 0;
 22 }
 23
 24 PNode createList()
 25 {
 26     int len, value;
 27
 28     PNode pHead = (PNode)(malloc(sizeof(Node)));
 29     PNode pTail = pHead;
 30     pTail->pNext = NULL;
 31
 32     printf("请输入你要的节点个数:");
 33     scanf("%d", &len);
 34     for(int i=1;i<=len;i++){
 35         printf("请输入第%d个节点的值:", i);
 36         scanf("%d", &value);
 37
 38         PNode pNew = (PNode)malloc(sizeof(Node));
 39         pNew->data = value;
 40         pTail->pNext = pNew;
 41         pTail = pNew;
 42         pTail->pNext = NULL;
 43     }
 44
 45     return pHead;
 46 }
 47
 48
 49 void traverse(PNode pHead)
 50 {
 51     printf("遍历结果为:\n");
 52     PNode pTra = pHead;
 53     while(pTra->pNext != NULL)
 54     {
 55         printf("%d ", pTra->pNext->data);
 56         pTra = pTra->pNext;
 57     }
 58     printf("\n");
 59 }
 60
 61 bool isEmpty(PNode pHead)
 62 {
 63     if(pHead->pNext==NULL)
 64       return true;
 65     else
 66       return false;
 67 }
 68
 69 int length(PNode pHead)
 70 {
 71     int len = 0;
 72     while(pHead->pNext!=NULL){
 73         pHead = pHead->pNext;
 74         len++;
 75     }
 76     return len;
 77
 78 }
 79
 80 bool insert(PNode pHead, int pos, int val)
 81 {
 82     if(pos<1 || pos>length(pHead)){
 83         return false;
 84     }else{
 85         PNode pInsert = pHead;
 86         for(int i=1;i<pos;i++){
 87             pInsert = pInsert->pNext;
 88         }
 89
 90         PNode pNew = (PNode)malloc(sizeof(Node));
 91         pNew->data = val;
 92         pNew->pNext = pInsert->pNext;
 93         pInsert->pNext = pNew;
 94
 95         return true;
 96     }
 97
 98 }
 99
100 bool del(PNode pHead, int pos)
101 {
102     if(pos<1 || pos>length(pHead)){
103         return false;
104     }else{
105         PNode pDel = pHead;
106         for(int i=1;i<pos;i++){
107             pDel = pDel->pNext;
108         }
109
110         if(pos==length(pHead)){
111           free(pDel->pNext);
112           pDel->pNext = NULL;
113         }else{
114             PNode pNext = pDel->pNext->pNext;
115             free(pDel->pNext);
116             pDel->pNext = pNext;
117         }
118
119         return true;
120
121     }
122
123
124 }
125
126 PNode get(PNode pHead, int k)
127 {
128     PNode p = pHead;
129     for(int i=1;i<=k;i++){
130         p = p->pNext;
131     }
132     return p;
133
134 }
135 PNode locate(PNode pHead, int value)
136 {
137     PNode p = pHead->pNext;
138     while(p&&p->data!=value){      //NULL 是 0
139         p = p->pNext;
140     }
141     return p;
142 }

时间: 2024-08-22 08:36:41

单链表的实现及其基本操作的相关文章

JAVA实现具有迭代器的线性表(单链表)

一,迭代器的基本知识: 1,为什么要用迭代器?(迭代:即对每一个元素进行一次“问候”) 比如说,我们定义了一个ADT(抽象数据类型),作为ADT的一种实现,如单链表.而单链表的基本操作中,大部分需要用到依次遍历单链表中的每一个元素.一般而言,我们就是用for循环来实现遍历,这样,当你新增一个对单链表的操作并需要使用遍历时,你就得重新写一个for循环而实现遍历.那么,为什么不将迭代(遍历)作为一种基本的ADT操作(基本的ADT操作如:新增一个元素.删除一个元素)呢?于是,迭代器就出场了. 2,鉴于

数据结构之自建算法库——单链表

本文针对数据结构基础系列网络课程(2):线性表中第10课时单链表基本操作的实现,建立单链表数据存储结构基本操作的算法库. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 单链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:linklist.h,包含定义顺序表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef LINKLIST_H_INCLUDED #define LINKLIST_H_INCLUDED typedef

线性表带头结点的单链表的链式表示和实现

带有头结点的单链表的12个基本操作 #define DestroyList ClearList//DestroyList()和ClearList()的操作是一样的 void InitList(LinkList &L){ L = NULL; } void ClearList(LinkList &L){ LinkList p; while (L){ p = L; L = L->next; free(p); } } Status ListEmpty(LinkList L){ if (L)r

单链表的学习

链表是一种很重要的数据结构,它由两部分组成,第一个部分是我们要储存的数据,第二个部分是指向下一个储存单元的指针.链表在使用中有顺序表无法比拟的灵活性,免去了储存空间不够,又有可能浪费的尴尬. 单链表有一个头指针pHead,当我们没有数据要储存的时候它指向NULL,当我们有数据的时候它指向第一块储存单元.储存单元里面有两个部分,前面的部分是我们要储存的数据data,后面的部分是指向下一个储存单元的指针pNext,当后面没有储存单元的时候就指向NULL.那么我们储存的数据在内存中并不是连续储存的,而

python中的单链表实现

引子 数据结构指的是是数据的组织的方式.从单个数据到一维结构(线性表),二维结构(树),三维结构(图),都是组织数据的不同方式. 为什么需要链表? 顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活. 链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理. 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址).

数据结构复习--java实现单链表基本操作

单链表的基本操作包括建立单链表.查找运算(按序查找和按值查找).插入运算(前插和后插)和删除运算.下面给出具体的java实现程序: package com.zpp.test; //首先创建一个节点类 public class Node { private Node next; //指针域 private int data;//数据域 public Node( int data) { this. data = data; } } package com.zpp.test; public class

《实验课---单链表的基本操作》

//线性表---链表的基本操作#include<stdio.h>#include<stdlib.h>#include<conio.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define NULL 0typedef int Status; //函数结果状态代码typedef int ElemType; //数据元素类型//------线性表的单链表存储结构

数据结构实验报告-实验一 顺序表、单链表基本操作的实现

实验一    顺序表.单链表基本操作的实现   l  实验目的 1.顺序表 (1)掌握线性表的基本运算. (2)掌握顺序存储的概念,学会对顺序存储数据结构进行操作. (3)加深对顺序存储数据结构的理解,逐步培养解决实际问题的编程能力. l  实验内容 1. 顺序表 1.编写线性表基本操作函数: (1)InitList(LIST *L,int ms)初始化线性表: (2)InsertList(LIST *L,int item,int rc)向线性表的指定位置插入元素: (3)DeleteList1

C语言实现单链表(带头结点)的基本操作

我在之前一篇博客<C语言实现单链表(不带头结点)的基本操作>中具体实现了不带头结点的单链表的11种操作:如计算链表长度.初始化.创建链表.清空链表等等.但是在实际使用中,带头结点的单链表往往比不带头结点的单链表用的更多,使用也更为方便.因为不用单独考虑第一个节点的情况了,第一个节点和其他后续节点的处理全都一样了,简化操作.这篇博客将会来实现带头结点的单链表的11种操作.代码上传至: https://github.com/chenyufeng1991/LinkedList_HeadNode  .