1.单链表的删除操作实战
思路:判断i值是否合法 >> 找到第i-1个元素 >> 删除第i个元素并释放对应结点空间 >> 结束
代码:
LinkList list_pos_search(LinkList L,ElemType search_pos)
{
if(search_pos<0)
{
return NULL;
}
int j;
for(j=0;j<search_pos;j++)
{
L=L->next;
}
return L;
}
bool list_delete(LinkList L,ElemType delete_figure)
{
LinkList m;
m=list_pos_search(L,delete_figure-1);
if(NULL==m)
{
return false;
}
LinkList n;
n=m->next;
m->next=n->next;
free(n);
return true;
}
注意:删除链表过程中头结点没有赋值、没有申请空间,就叫没有改变头结点,子函数就不需要加“&”符号
举例:删除第一个结点时,头指针的指针域会被赋予NULL(这种不算改变头指针)。而利用头插和尾插创建链表当然改变了头指针,这是从无到有的过程
2.考研真题实战
题目:
思路分析:
找到中间结点 >> 对后半部分进行逆置 >> 重新合并两个链表
1>设计思想
2>代码实战
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct node{
ElemType data;
struct node *next;
}NODE,*LinkList;
void list_tail_insert(LinkList &L)
{
L=(LinkList)malloc(sizeof(NODE));
ElemType x;
scanf("%d",&x);
LinkList s,r=L;
while(x!=9999)
{
s=(LinkList)malloc(sizeof(NODE));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
}
void print_list(LinkList L)
{
L=L->next;
while(L)
{
printf("%3d",L->data);
L=L->next;
}
printf("\n");
}
void divide_list(LinkList L,LinkList &L2)
{
L2=(LinkList)malloc(sizeof(NODE));
LinkList p,q;
p=q=L->next; //这两行代码可优化为1行
// q=L->next;
while(p)
{
p=p->next;
if(NULL==p)
{
break; //return; //这里不应该是return,而是break
}
p=p->next;
if(NULL==p)
{
break; //return; //这里不应该是return,而是break
}
q=q->next;
}
L2->next=q->next;
q->next=NULL;
}
void reverse(LinkList L2)
{
LinkList r,s,t;
r=L2->next; //下方应该增加r为空的判定条件,即L2链表内无元素的情况就不需要逆转了
if(NULL==r)
{
return;
}
s=r->next;
if(NULL==s)
{
return;
}
t=s->next;
// while(s) //循环条件设定为t
// {
// s->next=r;
// if(NULL==t) //以下三行(含本行)不应这样设置
// {
// break;
// }
// t=t->next; //假若t的下一个结点是NULL,则会造成宕机,导致r、s和t全部为NULL
// s=t;
// r=s;
// }
// //循环结束还需要s->next=r反向链接一次,否则接不上
while(t)
{
s->next=r;
r=s;
s=t;
t=t->next;
}
s->next=r;
L2->next->next=NULL;
L2->next=s;
}
void merge(LinkList L,LinkList L2) //合并L2不需要加引用,这是错误的,加不加引用永远只看改变头指针没有
{
LinkList pcur,p,q;
pcur=L->next;
q=L2->next;
p=pcur->next;
while(p!=NULL&&q!=NULL)
{
pcur->next=q;
pcur=pcur->next;
q=q->next;
pcur->next=p;
p=p->next;
pcur=pcur->next;
} //循环结束后还存在L或L2链表中谁多一个元素的问题,所以需要加上if来将各自多的结果链接上pcur
if(p!=NULL)
{
pcur->next=p;
}
if(q!=NULL)
{
pcur->next=q;
}
}
int main() {
LinkList L;
list_tail_insert(L);
print_list(L);
printf("********************\n");
LinkList L2;
divide_list(L,L2);
print_list(L);
print_list(L2);
printf("********************\n");
reverse(L2);
print_list(L2);
printf("********************\n");
merge(L,L2);
free(L2); //合并后要free掉L2链表的内存占用
print_list(L);
return 0;
}
3>时间复杂度分析