知识点回顾:
单链表类型定义:
//类型定义typedef struct Lnode{ ElemType data;struct Lnode *next; }Lnode, *LinkList//变量定义LinkList L;//注意此处是不加 * 的,原因看类型变量的结构体变量形式Lnode *p,*s;//注意此处是加 * 的。原因如上//重要操作p=L;//p指向头结点s=L->next;//s指向首元结点p=p->next;//p指向下一结点//单链表的基本操作://单链表的销毁Status DestroyList_L(LinkList &L){//用于指向要销毁的结点Lnode *p;//循环条件,链表L非空(这是传入的参数)while(L){//让 指针p 用于指向要销毁的链表的头结点p = L;//让原本指向头结点的 指针L 指向下一个结点L = L->next;//释放 指针p 指向结点的内存。 delete p; }return OK; }//清空单链表Status ClearList(LinkList &L){ Lnode *p, *q;//让指针p指向首元结点,即从首元结点开始清理,而非头结点!p = L->next;while(p){//指针q 指向 指针p 所指向结点的下一个结点q = p->next; delete p; p=q; } L->next = NULL;return OK; }//求单链表的表长int ListLength_L(LinkList L){//定义一个 指针p 用以指向传入的单链表 LinkList p; p=L->next; i=0;while(p){ i++; p=p->next; }return i; }
取值:取单链表中第 i 个元素的内容。
思考:顺序表里如何找到第i个元素?L->elem[i-1];
算法思路(分别取出表中第3个元素和第15个元素)
① 先找到首元结点,定义一个指针p,让其指向首元结点,即L->next,同时定义变量 j=1;
② 一直循环往下走,然后 j++,直到 j=3 时,获取 p->data ,也就是指针P所指向结点的数据域;
链表查找数据时,从链表的头指针出发,顺着链域next逐个结点往下搜索,直至搜索到第i个结点为止,
因此链表不是随机存取结构。
③ 如果要找第15个元素,再继续的话,将指向空的,即没有元素,因此不需要继续向下寻找。
④ 注意 第几个元素 限制,初始值只能为 1 ,小于这个,肯定就是错的
算法步骤:
① 从第一个结点(L->next)顺链扫描,用 指针p 指向当前扫描到的结点,p初值 p=L->next;
② j 做计数器,累计当前扫描过的结点数,j 初值为1;
③ 当 指针p 指向扫描到的下一结点时,计数器 j 加1;
④ 当 j == i 时,指针p 所指的结点就是要找的第 i 个结点。
代码部分:
//获取线性表 L 中的某个数据元素的内容,通过变量 e 返回//为什么要用&,这里要改变指针 变量e 本身的值,//而非改变 e 所指内容的值!//从链表 L 中获取第 i 个元素,元素的值由变量 e 返回。Status GetElem_L(LinkList L, int i, ElemType &e){//初始化,给 指针p 赋值,跳过头结点,指向首元结点p = L->next;//初始化,定义一个计数器,初始值为1j = 1;//向后扫描,直到 指针p 指向第 i 个元素或 指针p 为空//当 j==i 时,即找到此元素,因此 j<i 不再成立,循环停止//当 i<1 时,即传入 i 不合法,因此无法找到,也不成立 //当 p为NULL 时,即找到最后都没找到,循环也停止while(p && j<i){ p = p->next;//这里 j++ 和 ++j 都可以,对代码功能不会造成影响++j; }//当指针为空,或者计数变量j大于i时,就证明运行出现了错误if(!p || j>i){return ERROR; } e = p->data;return OK; }