仅供参考:
链表分单向,双向,循环三种。
链表的基本操作包括:顺序建表,逆建,结点插入,删除,链表的合并,拆分等。
顺建:需要定义三个结构体指针***head, t, p。申请头结点head----head->next=NULL----t=head
下面插入结点:p->next=NULL----t->next=p----t=p;(尾节点要一直指向当前最后结点)。
逆序建链表:定义两个结构体指针****head, *p。***让头结点一直指向当前最后一个结点,这样当所有结点插入完成以后就可以从最后一个结点逆序访问输出(每插入一个结点p,最后一条指令都是head->=p,让头指针指向当前结点)
继而,当插入下一个结点p时,因为head->要指向当前的p,所以要将head与上一个p分开,但是,在分开之前,要让当前的p记下上一个p的地址,即:p->next=head->next(上一个p的地址已经由head->记下),然后,就可以放心地让head->指向当前的p了。
固建完头结点后的代码为:
p->next=head->next;
head->next=p;
插入结点:
下面是给一个空表插入结点的代码
void insert(int a,int b)
{
struct st *p,*q;
p=head;
for(i=0;i<a&&i<len;i++)//***len,head***是前面定义的全局变量 // i和len从0开始
{
p=p->next;}
q=.......;//申请空间
q->data=a;//给p的数据域赋值a.
q->next=p->next;
p->next=q;
len++;//总结点数加一。
若是在一个不是空的链表插结点,只需要找到要插入的位置然后插进去即可,若要在某个数后面插入结点与在第n个结点后(与上面代码差不多)插入结点,操作稍微有点不同。
下面直写在某个数后面插结点:
p=head->next;
while(p!=NULL)
{
if(p->data==key)
{
q=.........;
scanf("%d",&q->data);
q->next=p->next;
p->next=q;
}
else p=p->next;
}
return head;
删除结点: //此处未完待续…
p=q->next;
首先找到利用游动指针q找到要删除的点,然后p->next=q->next
拆分:
假设要将一个表按奇偶性分成两个表
void sp(struct st*h) //不需要返回值的都用void.本题若用return返回头指针的方法是不行的,因为return只能返回一个值。所以干脆把h1,h2变成全局变量,这样主函数和自定义函数都能直接使用。
{
struct st*p;
p=h->next; //p从第一个点开始以次访问。
h1=.......;
h2=.......;
h1->next=NULL; //申请两个只有头结点的空表。
t1=h1;
h2->next=NULL:
t2=h2;
while(p!=NULL)
{
if(p>data%2==0) //若p的数据域为偶数,则与头指针h1相连。
{t1->next=p;t1=h1;p=p->next;
}
else {t2->next=p;t2=p;p=p->next
}
}
t1=NULL;t2=NULL; //次处不可少,做事情都要有始有终哦。
}
合并:
这里写代码片struct st *he(strucct st*h1,struct st *h2)
{
struct st*head,*t,*p1,*p2;
head=.......;
head->next=NULL; // 先类似于顺建建一个只有头结点的空表。
t=head;
p1=h1->next;
p2=h2->next;
while(p1&&p2)
{
if(.....)下面根据具体条件,把p1,或者p2接到t后面;例如:
{t->next=p2;
t=p2;
p2=p2->next; //p2指向下一个结点再与p1比较看谁满足条件。
}
}
if(p1) //执行完上面的while后,必定有一个链表为空了,或者两个都空了。若p1还不空, 把p1后面的结点一块都接在t的后面。
{
t->next=p1;
}
else t->next=p2;
return head; //把合并后的头指针返回。
}