前言
链表是数据结构中非常重要的一种线性结构,它在线性结构中是离散存储的。在讲链表之前,先谈下typedef(为数据类型取别名)的用法,因为typedef在定义结构体时经常用到,可以起到很好的简化数据类型书写的作用。
实例说明:
#include<stdio.h>
typedef struct Student
{
int sno;//学号
char name[20];//姓名
}*PST,ST;//PST代表了struct Student *,ST代表了struct Student,即分别为其数据类型取别名
int main()
{
ST s={1001,"张三"};
PST pst=&s;
printf("学号:%d\n姓名:%s\n",pst->sno,pst->name);
return 0;
}
链表
链表可理解为n个结点(由数据域和指针域两部分组成)离散分配,彼此通过指针相连,每个结点只有一个前驱结点(除首节点外),每个结点只有一个后继结点(除尾结点外),且每个结点的数据类型相同。
链表中常见的专业术语有:首节点(第一个有效结点,即存放了有效数据),尾结点(最后一个有效结点,指针域为NULL),头结点(是在首结点前附加的一个节点,它没有存放有效数据,也没有存放有效结点个数。在首结点前加一个实际含义的头结点,可以方便我们对链表进行操作),头指针(存放了头结点的地址,即指向了头结点),尾指针(指向结点的地址)。我们通常只需要头指针通过一个函数来对链表进行处理,通过头指针就可以推算出链表的其他信息。链表的分类有:单链表(每个结点指针只能指向后一个结点--尾结点除外),双链表(每个结点有两个指针域,前一个指针域指向前驱结点,后一个指针域指向后继结点),循环链表(能通过任何一个结点找到其它结点--尾结点可以指向头结点),还有非循环链表等;
结点的表示
typedef struct Node
{
int data;//数据域
struct Node *pNext;//指针域,指向本身和它一样的结构体(数据类型)
}NODE,*PNODE;//NODE等价于struct Node,PNODE等价于struct Node*
链表的创建和遍历
实例说明:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct Node
{
int data;//数据域
struct Node *pNext;//指针域
}NODE,*PNODE;
PNODE CreateList(void);//void表示无形参
void TraverseList(PNODE);//此处省略形参名
int main()
{
PNODE pHead=NULL;
pHead=CreateList();//创建链表,并将返回的头结点的地址赋给pHead
TraverseList(pHead);//遍历链表
return 0;
}
PNODE CreateList(void)
{
int len;//用来存放有效结点的个数
int i;
int val;//用来临时存放用户输入结点的值
PNODE pHead=(PNODE)malloc(sizeof(NODE));//动态分配一个块内存,该内存用来存放头结点
PNODE pNew;
PNODE pTail=pHead;
pTail->pNext=NULL;
if(NULL==pHead)
{
printf("分配失败,程序终止!\n");
exit(-1);//终止程序运行
}
printf("请输入您要创建链表的结点个数:len=");
scanf("%d",&len);
for(i=0;i<len;i++)
{
printf("请输入第%d个结点的值:",i+1);
scanf("%d",&val);
pNew=(PNODE)malloc(sizeof(NODE));//每循环一次,动态分配一个新临时结点
if(NULL==pNew)
{
printf("分配失败,程序终止!\n");
exit(-1);
}
pNew->data=val;//为新节点数据域赋值
pTail->pNext=pNew;//将新节点挂到尾结点后面
pNew->pNext=NULL;//将新节点的指针域设为空
pTail=pNew;//每次循环,让新节点成为尾节点
}
return pHead;
}
void TraverseList(PNODE pHead)
{
PNODE p=pHead->pNext;//此时p指向首节点
while(p!=NULL)
{
printf("%d ",p->data);
p=p->pNext;//将p的指针域指向下一个结点(指针域为空时,说明已经到了尾结点)
}
printf("\n");
}
注意
1. 第一个结点的指针域指向下一个结点(地址)的整体信息。
2.若p指针指向某个结点(头结点和尾结点除外),则p本身没有指针域,p指向的那个结构体变量(结点)才有指针域。
分享到:
相关推荐
简单实用的创建和遍历链表代码
链表的创建和遍历。这是一个最基本的操作,元素类型定义为int 本源程序包含了链表的创建和遍历操作
本文将深入探讨如何在C语言中创建和遍历动态链表,这对于初学者来说是非常基础且重要的概念。 首先,我们需要了解动态链表的基础构造。链表由一系列节点组成,每个节点包含两部分:数据域,用于存储实际的数据;...
本文主要讲解了C语言中数组和链表的概念及操作,包括数组指定位置插入和删除、链表的结构、静态链表和动态链表、单链表的建立和遍历、双向链表的概念、循环链表的概念等。同时也涉及到了链表的实战应用和拓展思维。 ...
C语言快速提升之链表的创建与遍历
本篇文章将深入探讨单向链表的基本概念,包括其结构体定义、如何创建链表以及如何遍历链表。 首先,我们来理解链表的结构。在C语言中,单向链表通常用结构体来表示。结构体包含两个部分:数据域,用于存储实际的...
线索链表是在二叉链表的基础上增加了结点的前驱和后继,若一结点的左指针为空,则指向其前驱,若右结点为空,则指向其后继结点。
C语言
链表实现二叉树创建和遍历,三种遍历方式实现,二叉树
这个VC工程提供了一个学习单链表操作的例子,包括创建链表、遍历链表和删除链表节点。 1. **创建单链表**: 创建单链表的过程是从无到有建立链表的过程。首先,需要定义一个链表节点结构,通常包含一个数据域和一...
链表是一种基础且重要的数据结构,...总结,链表创建与遍历是理解和掌握链表数据结构的基础。理解这些概念和算法对于编程和解决实际问题至关重要,尤其是在处理需要频繁插入、删除操作的数据集时,链表的优势尤为明显。
1. **链表创建**: 创建链表首先需要定义一个结构体类型来表示链表的节点,通常包含数据部分和指向下一个节点的指针。例如: ```c typedef struct Node { int data; struct Node* next; } Node; ``` 初始化...
链表的操作主要包括创建、插入、删除和遍历等。在给定代码中,主要涉及到了创建和插入操作,以及最终的遍历显示结果。这些操作是基于结构体`struct student`实现的,其中包含了学号、成绩和指向下一个节点的指针。 ...
4. **链表操作**:我们需要创建一个链表,插入复数,遍历链表以及销毁链表。插入操作通常包括创建新节点、设置节点值和连接到链表中。遍历链表则是沿着链表节点的指针顺序访问每个节点。 5. **复数加法**:复数加法...
二叉树遍历算法可以分为三种:前序遍历、中序遍历和后序遍历。 (1)前序遍历 前序遍历是指从根节点开始,先访问当前节点,然后访问左子节点和右子节点。下面是一个简单的前序遍历算法: ```c void ...
首先定义了链表的基本结构和操作,包括创建节点、添加节点、删除节点和遍历链表等。接着通过具体示例演示了如何在 Python 中实现单链表的基本操作。文章还讨论了链表在电话簿管理和音乐播放列表中的实际应用,并介绍...
C++先序遍历的顺序建立二叉链表,
在实际编程中,结合先序创建二叉树和层次遍历可以解决很多复杂的问题,比如搜索、排序等。通过对这些基本概念和技术的理解和掌握,可以有效地提升程序员的算法设计与分析能力,从而避免成为所谓的“代码民工”。 ...
3. **链表逆置**:在不创建新节点的情况下,链表逆置可以通过三个指针(当前节点、前一个节点和临时节点)来完成。遍历链表,每次将当前节点的指针指向前一个节点,然后更新前一个节点为当前节点,当前节点为下一个...
1.先序创建 2.先序遍历递归算法 3.中序遍历递归算法 4.后序遍历递归算法 5.先序遍历非递归算法 6.后序遍历非递归算法 7.中序遍历非递归算法 8.二叉树求深度 9.左孩子右兄弟链表创建树并求深度