引入
今天看到一个有关链表插入的题,题目大概是给一组有序的链表,要插入一个值,再有序的把这个链表输出。我的第一个想法是声明两个指针,一前一后共同找插入的位置,后面的指针指向比插入的值大于或等于的位置,然后把新节点的指针域连接到后面指针指向节点,前面的指针的指针域指向新节点,这样就完成了。后来我又想可不可以用一个指针就可以解决这个问题,所以就想到了二级指针。
思路
插入
什么是二级指针呢,就是指向指针的指针。在插入函数中传入这个链表头节点的指针域(第一个节点的位置),我们只需要声明一个指针,这个指针就指向二级指针保存的地址(也就是下一个节点)。当找到合适的插入位置之后,新的节点指针域指向当前位置,那个二级指针解引用后指针指向新的节点,这个新节点就插入好了!
文字可以表达不是很清楚,画图表示下,比如要插入数字4,plink是二级指针,指向头指针的指针项link,current是一个指向节点的一级指针。注意查看每个指针所指向的位置。
删除
和上面的操作思路差不多,我们来看下删除的图解,假设删除链表里面的数字5,使用二级指针代码感觉更简洁。
代码
附上代码里面包含链表的创建和遍历。
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct Node{
int date;
struct Node *Link;
}NODE;
NODE *Create(); //创建链表//
bool Insert(NODE **pLink,int val); //在链表插入值//
bool Delete(NODE **Head,int val); //在链表删除值//
void Traverse(NODE *Head); //遍历链表//
int main (){
NODE *Head;
Head=Create();
Insert(&Head->Link,4);
Delete(&Head->Link,5);
Traverse(Head);
return 0;
}
NODE *Create(){
NODE *Head,*Tail,*New;
int n,val;
Head=(NODE*)malloc(sizeof(NODE));
Head->Link=NULL;
Tail=Head;
printf("Please enter the number of nodes:\n");
scanf("%d",&n);
for (int i = 0; i <n ; ++i) {
New=(NODE*)malloc(sizeof(NODE));
if (New==NULL)
exit(-1);
scanf("%d",&val);
New->date=val;
New->Link=NULL;
Tail->Link=New;
Tail=New;
}
return Head;
}
void Traverse(NODE *Head){
NODE *p;
p=Head->Link;
while (p!=NULL)
{
printf("%d ",p->date);
p=p->Link;
}
printf("\n");
}
bool Insert(NODE **pLink,int val){
NODE *Current,*New;
while ((Current=*pLink)!=NULL && Current->date<val)
{
pLink=&Current->Link;
}
New=(NODE*)malloc(sizeof(NODE));
New->date=val;
New->Link=Current;
*pLink=New;
return true;
}
bool Delete(NODE **pLink,int val){
NODE *Current;
while ((Current=*pLink)!=NULL && Current->date!=val)
{
pLink=&Current->Link;
}
if (Current==NULL) //没有找到相应值//
return false;
*pLink=Current->Link;
free(Current);
return true;
}