#include<stdio.h>
#include<stdlib.h> //exit的头文件
#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode;
typedef struct LNode *LinkList;
typedef int Status;
//在调用函数前指针为空,在函数中为指针分配了新结点,而不是原来的结点,此时只能采用&引用或者指向指针的形式,LinkList &L,LinkList *L;
//在调用函数前指针不为空,在函数中对结点进行插入和删除操作,则可以采用引用传递或者指针传递,LinkList &L,LinkList L;
Status InitList(LinkList *L) //这里传递的参数是LinkList *L,是双重指针,应该理解为指向指针的指针,而不是理解为结点LNode,把指针的地址传过来了,对*L进行修改的话,也就对地址中的内容做了修改,也就对传进来的参数做了修改;这个地方不是LinkList L,因为最初传递进来的位置是NULL,如果是这样的话,L只是一个副本,使L指向空,但是函数中为L分配结点,并且结点的next指向空,这个返回不到传进来的参数里去,最终L成为了局部变量
{
(*L)=(LinkList)malloc(sizeof(LNode)); //(*L)就是取出L所指向的内容
if(!(*L))
exit(OVERFLOW);
(*L)->next=NULL;
return OK;
}
Status ClearList(LinkList L) //清空链表保留头节点,所以调用函数前指针不为空,指针传递就行
{
LinkList p,pre;
if(!L)
return ERROR;
pre=L->next;
while(pre)
{
p=pre->next;
free(pre);
pre=p;
}
L->next=NULL;
return OK;
}
void DestoryList(LinkList *L) //头结点也被销毁了,所以传递的是指向指针的形式
{
LinkList p=*L; //作为参数时,LinkList *L中L是指向指针的指针,在函数中,*L是L指向的内容,就是指针,就是指向头结点的指针了,一层一层分析
while(p)
{
p=(*L)->next;
free(*L);
(*L)=p;
}
}
Status ListEmpty(LinkList L) //链表存在但是只有头结点
{
if(L!=NULL&&L->next==NULL)
return TRUE;
else return FALSE;
}
int ListLength(LinkList L)
{
LinkList p;
int i;
if(L) //考虑到L不为空的情况
{
i=0;
p=L->next;
while(p)
{
i++;
p=p->next;
}
}
return i;
}
Status GetElem(LinkList L,int i,ElemType *e)
{
LinkList p;
int j=1; //因为从第一个结点开始,j表示第几个结点,所以从1开始
p=L->next;
while(p&&j<i) //因为要找第i个结点元素,每一次会有p=p->next,所以控制j<i,找到了前面这个结点,循环中有p=p->next所以最后第i个结点是p
{
p=p->next;
j++;
}
if(!p||j>i) //最后如果找到的话j=i,所以如果j>i的话就出错了,而且要保证前面的都是非空结点
return ERROR;
*e=p->data;
return OK;
}
int LocateElem(LinkList L,ElemType e,Status (compare)(ElemType,ElemType))
{
LinkList p;
int i;
if(L)
{
i=1;
p=L->next;
while(p&&!compare(e,p->data)) //相等的时候没有进入循环,所以i没有++,Locate返回的是位序,所以i从1开始
{
i++;
p=p->next;
}
}
if(p)
return i;
else return 0;
}
Status compare(ElemType e1,ElemType e2)
{
if(e1==e2)
return TRUE;
else return FALSE;
}
Status PriorElem(LinkList L,ElemType cur_e,ElemType *pre_e) //找的是前一个
{
LinkList p;
if(L)
{
p=L->next;
if(L->next&&L->next->data!=cur_e) //第一个没有前驱
{
while(p->next&&p->next->data!=cur_e) //所以看后面一个
p=p->next;
if(p->next)
{
*pre_e=p->data;
return OK;
}
}
}
return ERROR;
//LinkList p, suc;
//
// if(L)
// {
// p = L->next;
//
// if(p->data!=cur_e) //第一个结点无前驱
// {
// while(p->next) //若p结点有后继
// {
// suc = p->next; //suc指向p的后继
// if(suc->data==cur_e)
// {
// *pre_e = p->data;
// return OK;
// }
// p = suc;
// }
// }
// }
//
// return ERROR;
}
Status NextElem(LinkList L,ElemType cur_e,ElemType *next_e)
{
LinkList p;
if(L)
{
p=L->next;
while(p->next&&p->data!=cur_e) //看p的data但是p->next不为空
p=p->next;
if(p->next)
{
*next_e=p->next->data;
return OK;
}
}
return ERROR;
// LinkList p, suc;
//
// if(L)
// {
// p = L->next;
//
// while(p && p->next)
// {
// suc = p->next;
//
// if(suc && p->data==cur_e)
// {
// *next_e = suc->data;
// return OK;
// }
//
// if(suc)
// p = suc;
// else
// break;
// }
// }
//
// return ERROR;
}
Status ListInsert(LinkList L,int i,ElemType e)
{
LinkList p,s;
p=L;
int j=0;
while(p&&j<i-1) //p是前驱
{
p=p->next;
j++;
}
if(!p||j>i-1)
return ERROR;
s=(LinkList)malloc(sizeof(LNode));
if(!s)
exit(OVERFLOW);
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
Status ListDelete(LinkList L,int i,ElemType *e)
{
LinkList p=L,q;
int j=0;
while(j<i-1&&p->next) //p是其前驱
{
p=p->next;
j++;
}
if(!p->next||j>i-1)
return ERROR;
q=p->next;
p->next=q->next;
*e=q->data;
free(q);
return OK;
}
void ListTraverse(LinkList L,void (visit)(ElemType))
{
LinkList p;
if(!L)
return ERROR;
else
p = L->next;
while(p)
{
visit(p->data);
p = p->next;
}
return OK;
}
void PrintList(LinkList L)
{
LinkList p;
if(L)
{
p=L->next;
printf("链表的元素有:\n");
while(p)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
else printf("链表为空");
}
void CreateList(LinkList *L,int n)
{
(*L)=(LinkList)malloc(sizeof(LNode)); //头结点
(*L)->next=NULL;
int i;
LinkList p;
for(i=n;i>0;i--)
{
p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=(*L)->next;
(*L)->next=p;
}
}
void MergeList(LinkList *L1,LinkList *L2,LinkList *L3)
{
LinkList pa,pb,pc;
pa=(*L1)->next;
pb=(*L2)->next;
pc=(*L3)=(*L1);
while(pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=pa?pa:pb;
free(*L2);
}
int main()
{
// LinkList L;
// InitList(&L);
// int n;
// scanf("%d",&n);
// int i,a,b=0,c=0,d=0,p=0,q=0; //刚开始p,q没有初始化,又没有前驱后继就是乱码
// for(i=1;i<=n;i++)
// {
// scanf("%d",&a);
// ListInsert(L,i,a);
// }
// PrintList(L);
//
// ListDelete(L,3,&b);
// printf("被删除的元素是:\n");
// printf("%d\n",b);
// PrintList(L);
//
// c=ListLength(L);
// printf("该链表的长度是是:\n");
// printf("%d\n",c);
//
// d=LocateElem(L,4,compare);
// printf("该元素在链表中的位置是:\n");
// printf("%d\n",d);
//
// PriorElem(L,5,&p);
// printf("该元素的前驱是:\n");
// printf("%d\n",p);
//
// NextElem(L,4,&q);
// printf("该元素的后继是:\n");
// printf("%d\n",q);
LinkList L1,L2,L3;
// InitList(&L1);
// InitList(&L2);
// int a,b,c,d,i;
int a,b;
scanf("%d%d",&a,&b);
CreateList(&L1,a);
CreateList(&L2,b);
// for(i=1;i<=a;i++)
// {
// scanf("%d",&c);
// ListInsert(L1,i,c);
// }
// for(i=1;i<=b;i++)
// {
// scanf("%d",&d);
// ListInsert(L2,i,d);
// }
PrintList(L1);
PrintList(L2);
MergeList(&L1,&L2,&L3);
PrintList(L3);
return 0;
}
测试结果:
2 3
5 4
3 2 1
链表的元素有:
4 5
链表的元素有:
1 2 3
链表的元素有:
1 2 3 4 5
Process returned 0 (0x0) execution time : 28.019 s
Press any key to continue.
来源:CSDN
作者:雾里看花花里看雾
链接:https://blog.csdn.net/qq_43779149/article/details/104111571