您的位置:首页 > 其它

链表的基本操作之插入、删除、逆置

2016-05-29 15:48 281 查看
上一篇写了有关链表的创建和遍历等相关内容,今天就来讲讲有关链表的其他操作吧。

提到链表,无非就是指针指来指去,最终连成一个链。好多人困惑的地方就在于p->next=r->next,指针到底是如何指向的,弄清楚这个,删、查、排的操作也就很容易弄懂了。大家都知道‘=’是赋值运算符吧,它左边是变量,右边是常量,既然了解了这些,那么让我们回到p->next=r->next这个表达式上,p->next既然是变量,它表示p这个指针的next的指向,而r->next是常量,它代表的是r指针的next的指向的位置,综合一下左右两端,就是p这个指针的下一个指向是r指针的next的指向的位置。可能这样有点绕,但你画个图,结合这句话,相信你一定会懂得。

先来讲一下插入吧,前面不是创建链表时讲了头插和尾插法嘛,其实就是那样的思想,只不过这只是插一个元素,插完后就要将链表连起来,注意一定要先连接的是后面。插入分为三种,头插、尾插、在中间随机插。在这儿我们就以不带头结点的创建链表的方式为例吧,在这儿就只写插入的代码吧。

struct Node *Insert(struct Node *head)//头插法
{
struct Node *p;
p=(struct student *)malloc(sizeof(struct student));
scanf("%d",&p->date);
p->next=head;
head=p;
return head;
}
struct Node *Insert(struct Node *head)//尾插法
{
struct Node *p,*t=head;
while(t&&t->next!=NULL){
t=t->next;
}
p=(struct student *)malloc(sizeof(struct student));
scanf("%d",&p->date);
t->next=p;
p->next=NULL;
return head;
}
struct Node *Insert(struct Node *head,int Date)//在链表中插入
{
struct Node *p,*t=head;
while(t&&t->date!=Date){
t=t->next;
}
p=(struct student *)malloc(sizeof(struct student));
scanf("%d",&p->date);
p->next=t->next;
t->next=p;
return head;
}


至于用头插法和尾插法创建的链表,我们就需要做点小小的改动,因为我们知道它们创建的链表的头结点都是空的,没有数据域,因此我们在对它们操作时,就要从head->next 开始,这样插入的头插法就有点变动了,有点类似在链表中插入,具体的可以自己试试,万一还是搞不定,可以留言哦!

现在我们来说说删除吧,删除我们要关心的两个方面是:一、数据重复,二、数据不存在,以前一直用循环遍历链表,当它是否和要删除的结点一致,这样我们就忽略了这两点,当你不知道链表的数据时,如果用这样的删除方式,后果很严重的哦!现在就来看看删除的代码.

Linklist *delect(Linklist *h,int m)
{
Linklist *p=h,*t;
while(p->next!=NULL){
if(p->date != m){
t=p;
p=p->next;
}
else{
t->next=p->next;
p=t->next;
}
}
return h;
}


接下来就来说说逆置的操作吧,之前一直强调只要弄明白链表的指针指向,这些问题都会迎刃而解的。逆置的操作就是我先将链表拆封开,将head和最后的NULL连接起来,然后通过一个循环一直在head前插入,每次将新插入的点定义为head,最后整个链表又会重新连接起来,成为一个逆置的链表。思路就是这样的,但是链表的创建方式不同,具体操作也会有点小的变动。以下代码就是根据带头结点的创建方式逆置的。

struct Node *reserve(struct Node *h)
{
struct Node *p,*t;
p=h->next;
t=p->next;
p->next=NULL;
while(t!=NULL){
p=t->next;
t->next=h->next;
h->next=t;
t=p;
}
return h;
}


至于链表的排序,我也不知道具体该咋讲,都得靠自己对于链表的指针指向的正确理解。搞不懂的时候就得在纸上画出它的指向究竟是咋样的。这里就先给出选择排序的算法吧。

Linklist *sort(Linklist *head)/*选择排序*/
{
Linklist *temp1,*temp2,*q,*p;
for(q=head;q->next!=NULL;q=q->next)
for(p=q->next;p->next!=NULL;p=p->next)
{
if(p->next->data<q->next->data)
if(q->next==p)//当他们是相邻结点的情况
{
temp1=p->next;
p->next=p->next->next;
temp1->next=q->next;
q->next=temp1;
p=temp1;
}
else
{
temp1=p->next;
temp2=q->next;
p->next=p->next->next;
q->next=q->next->next;
temp1->next=q->next;
q->next=temp1;
temp2->next=p->next;
p->next=temp2;
}
}
return head;
}


好了,今天就说这么多吧,可能我的理解也有错误,还需各位指正啊!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表 指针