Data Structure ---SinglyLinkedList

喜你入骨 提交于 2020-01-31 05:44:03
#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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!