首先,我们要知道由于链式存储是一种“乱放”式存储方式,所以单链表没有表长的定义,这也意味着相关操作不能用for循环,因为不知道循环次数,只能用while循环!!其次,由于不同于顺序存储,不是在一片地址连续内存存储数据,所以我们的操作必须要用到一个工具为我们找到下一个元素,没错,就是指针!!
基本操作还是四大类:取,读,插,删。取和读是一个玩意儿,就放一起说。不同于顺序存储,我们想在一片随意分布的数据中找到我们想要的元素,只有一种方法,那就是从第一个开始遍历,找到第二个,再找到第三个,再找到第四个,一直到我们要找的第i个,所以要先声明一个结点,让它指向链表第一个结点,再依次后移,找到取出即可,大家会发现,取和读的平均时间复杂度是O(n)。
下面分别讲一下插入与删除操作。
插入操作:
1、声明一个结点p指向链表第一个结点,依次后移找到目标位置(p=p->next)
2、若到末尾仍未找到,说明不存在,返回ERROR
3、找到后,生成空结点s,s的数据域存放插入的元素,指针域的指针指向p->next(s->next=p->next)
4、让p指向s,p->next=s,返回OK
删除操作:
1、声明一个结点p指向链表第一个结点,依次后移找到目标位置(p=p->next)
2、若到末尾仍未找到,说明不存在,返回ERROR
3、找到后,假如要删去q结点,则执行绕开q操作,即:p->next=p->next->next或(q=p->next;p->next=q->next)
4、取出q结点中的值返回给e,释放q,返回OK
其实通过上述讲解,大家可以看到单链表这四种操作平均时间复杂度都是O(n),那这样看来不是比顺序存储还要麻烦吗?但是这只是对一个元素进行操作,假如我们要在同一个位置插入或删除很多元素,又会是怎样一种情况呢?显然,链式存储的优势就明显了,顺序存储遇上这种情况,每次的操作时间复杂度都是O(n),而链式存储从第二次开始都是O(1),所以对于删除或插入十分频繁的操作需要,单链表的效率就很“秀”了。
单链表是可以动态增加或减少的,不像顺序存储,申请空间是成片成片申请的,单链表是增加一个结点就加一块内存,我们接下来来看一下对单链表的整表删除与建立操作。
整表删除:
1、设置两个指针p和q,p指向第一个结点,q指向p后一个结点
2、删去p,释放p的空间,将q赋给p,即p=q,q继续指向p后一个(用while实现)
3、直至为空表,将头指针赋值为NULL(必须有!!)
整表建立:
一、换“头”建立法:
1、声明一个指针指向每次要加入单链表的新结点
2、新结点指针指向原第一个结点,让头指针指向新结点,实现“换头”,即新结点变成表头
3、重复操作
二、换”尾“建立法
1、声明两个指针,一个指针p指向新结点,一个指针r指向表尾
2、将新结点接到表尾后,即r->next=p
3、让r指向新结点,实现换尾,即r=p
4、最后不要忘记 r->next=NULL(单链表最后一个结点指针域为NULL)
BY ZJQ