一、链表创建
链表头插:
Node * creat_h ()
{
Node * pHead,* pNew;
pHead=(Node*)malloc(sizeof(Node));
pHead->next=NULL;
printf("请输入正整数:");
pNew=(Node*)malloc(sizeof(Node));
scanf("%d",&pNew->date);
while(pNew->date>0)
{
pNew->next=pHead->next; //**
pHead->next=pNew;//**
pNew=(Node*)malloc(sizeof(Node));
scanf("%d",&pNew->date);
}
free(pNew);
return pHead;
}
图解
标星号的为头插创建链表的核心。要强调一下:两句代码的顺序不能颠倒。结合图示,不难发现,若要是顺序颠倒,那么pHead的数据域被覆盖,以致于pNew指针域无法正常连接。
链表尾插:
Node * creat_wl()
{
Node * pHead,* pNew,*pEnd;
pHead=pEnd=(Node * )malloc(sizeof(Node));
pHead->next=NULL;
pNew=(Node * )malloc(sizeof(Node));
printf("请输入正整数:");
scanf("%d",&pNew->date);
while(pNew->date>0)
{
pEnd->next=pNew;
pNew->next=NULL;
pEnd=pNew;
pNew=(Node *)malloc(sizeof(Node));
scanf("%d",&pNew->date);
}
free(pNew);
return pHead;
}
- 对比观察代码不难发现:链表尾插比链表头插多了一个pEnd节点。
- 链表尾插就是pEnd标记pNew前一个节点,在没有数据时,pEnd初始化为pHead(即第一次插入pNew的前一个节点),进行第一次连接,之后不断让pEnd后移,连接,实现链表尾插。
二、链表逆置
Node *Inversion(Node*phead)
{
node *p,*q;
q=phead->next;
p=q->next;
while(p)
{
q->next=p->next;//相当于删除操作
p->next=phead->next; //头插
phead->next=p;//头插
p=q->next;//更新p的位置
}
return phead;
}
- 链表逆置其实质就是链表的头插。可以理解为先进行一次删除操作,再将删除了的节点头插连接。
- 纸上谈来终觉浅,绝知此事要躬行。所以自己一定要去画图,画图才能更好地理解链表的知识。
三、链表的增删改查
如果前面的知识掌握了,增删改查学起来是十分简单的。
增加:
void Add(Node * pHead) //插入到指定元素后面
{
Node * ptemp=pHead,*pNew;
int n;
printf("请输入你想插入在数字几后面:");
scanf("%d",&n);
while(ptemp&&ptemp->date!=n)//遍历链表查找指定数字
ptemp=ptemp->next;
if(ptemp==NULL)
printf("%d未找到\n",n);
else
{
pNew=(Node*)malloc(sizeof(Node));
printf("请输入要插入的数字:");
scanf("%d",&pNew->next);
pNew->next=ptemp->next; //**
ptemp->next=pNew; //**
}
}
- 星号两句位置不可颠倒,否则就会因发生覆盖而无法正常插入。
删除:
核心代码:
ptemp1->next=ptemp->next;
- 删除时先遍历链表,找到指定信息,执行核心代码,之后free掉删除的节点,删除即完成。
修改:
遍历到指定信息时,修改数据域。
查询:
实质就是遍历链表。