数据结构 单向链表

5 篇文章 0 订阅

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int ElemType;

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

LNode * InitList();//成功返回头节点 失败返回NULL
void DestroyList(LinkList LL);
void ClearList(LinkList LL);
int  InsertList(LinkList LL, unsigned int ii, ElemType *ee);
void PrintList(LinkList LL);
int  PushFront(LinkList LL, ElemType *ee);
int  PushBack(LinkList LL, ElemType *ee);
int  DeleteNode(LinkList LL, unsigned int ii);
int PopFront(LinkList LL);
int PopBack(LinkList LL);
int  LengthList(LinkList LL);
int IsEmpty(LinkList LL);
LNode *LocateNode(LinkList LL, unsigned int ii);
LNode *LocateElem(LinkList LL, ElemType *ee);
int InsertNextNode(LNode *pp, ElemType *ee);
int InsertPriorNode(LNode *pp, ElemType *ee);
int DeleteNode1(LinkList LL,LNode *pp);
LNode *MergeList(LinkList La,LinkList Lb);
void ReverseList(LNode *pp);

int main()
{
  LinkList LL=NULL;

  LL=InitList();


  printf("LL=%p\n",LL);

  ElemType ee;

  printf("在表中插入元素(1、2、3、4、5、6、7、8、9、10)。\n");
  ee=1;  InsertList(LL, 1, &ee);
  ee=2;  InsertList(LL, 1, &ee);
  ee=3;  InsertList(LL, 1, &ee);
  ee=4;  InsertList(LL, 1, &ee);
  ee=5;  InsertList(LL, 1, &ee);
  ee=6;  InsertList(LL, 1, &ee);
  ee=7;  InsertList(LL, 1, &ee);
  ee=8;  InsertList(LL, 1, &ee);
  ee=9;  InsertList(LL, 1, &ee);
  ee=10; InsertList(LL, 1, &ee);

  printf("length=%d\n",LengthList(LL));

  PrintList(LL);

  printf("在第5个位置插入元素(13)。\n");
  ee=13; InsertList(LL, 5, &ee);

  PrintList(LL);

  printf("在表头插入元素(11),表尾插入元素(12)。\n");
  ee=11; PushFront(LL, &ee);
  ee=12; PushBack(LL, &ee);

  PrintList(LL);

  printf("删除表中第7个结点。\n");
  DeleteNode(LL,7); PrintList(LL);

  printf("删除表中第一个结点。\n");
  PopFront(LL); PrintList(LL);

  printf("删除表中最后一个结点。\n");
  PopBack(LL); PrintList(LL);

  LNode *tmp;

  if ( (tmp=LocateNode(LL,3)) != NULL)
    printf("第3个结点的地址是=%p,ee=%d\n",tmp,tmp->data);

  ee=8;
  if ( (tmp=LocateElem(LL,&ee)) != NULL)
    printf("元素值为8的结点的地址是=%p\n",tmp);
  else
    printf("元素值为8的结点的地址是NULL,没找着。\n");

  printf("在结点%p之后插入66\n",tmp);
  ee=66;
  InsertNextNode(tmp,&ee);  PrintList(LL);

  printf("在结点%p之前插入55\n",tmp);
  ee=55;
  InsertPriorNode(tmp,&ee);  PrintList(LL);

  // ReverseList(LL); PrintList(LL);  // 反转链表。

  DestroyList(LL); LL=NULL;  // 销毁链表,LL置为空。
  // DestroyList2(&LL);       // 销毁链表,传入指针的地址,LL在函数中会置为空。
  // DestroyList3(LL);       // 销毁链表,C++的引用,LL在函数中会置为空。

  printf("LL=%p\n",LL);


  // 以下代码显示两个链表的合并,把两个有序的La和Lb合并成有序的Lc。
  LinkList La,Lb,Lc;

  La=InitList();
  Lb=InitList();
  Lc=InitList();

  ee=1;  PushBack(Lb, &ee);
  ee=2;  PushBack(La, &ee);
  ee=3;  PushBack(Lb, &ee);
  ee=4;  PushBack(Lb, &ee);
  ee=5;  PushBack(La, &ee);
  ee=6;  PushBack(Lb, &ee);
  ee=7;  PushBack(Lb, &ee);
  ee=8;  PushBack(Lb, &ee);
  ee=9;  PushBack(La, &ee);
  ee=10; PushBack(La, &ee);

  PrintList(La);
  PrintList(Lb);


  Lc=MergeList(La,Lb);

  PrintList(Lc);
  ReverseList(Lc);
  PrintList(Lc);

  DestroyList(La); La=NULL;
  DestroyList(Lb); Lb=NULL;
  DestroyList(Lc); Lc=NULL;


  return 0;
}

LNode*InitList()
{
    LNode *head=(LNode*)malloc(sizeof(LNode));
    if(head==NULL)
    {
        return NULL;
    }
    head->next=NULL;
    return head;
}

int InsertList(LinkList LL,unsigned int ii,ElemType *ee)
{
    if((LL==NULL)||(ee==NULL))
    {
        printf("链表LL或元素ee不存在。\n");
        return 0;
    }
    if(ii<1)
    {
        printf("插入位置(%d)不合法,应该在大于0。\n",ii);
        return 0;
    }
    LNode *pp=LL;
    int kk=0;
    while((pp!=NULL)&&(kk<ii-1))
    {
        pp=pp->next;
        kk++;
        // printf("pp=%p,kk=%d\n",pp,kk);
    }
    if(pp==NULL)
    {
        printf("位置(%d)不合法。\n",ii);
        return 0;
    }
    LNode *tmp=(LNode*)malloc(sizeof(LNode));
    if(tmp==NULL) return 0;

    memcpy(&tmp->data,ee,sizeof(ElemType));

    tmp->next=pp->next;
    pp->next=tmp;

    return 1;

}

int DeleteNode(LinkList LL,unsigned int ii)
{
    if(LL==NULL)
    {
        printf("链表LL不存在。\n"); return 0;
    }
    if(ii<1)
    {
        printf("删除位置(%d)不合法,应该在大于0。\n",ii);
        return 0;
    }

    LNode *pp=LL;

    int kk=0;
    while((pp!=NULL)&&(kk<ii-1))
    {
        pp=pp->next;
        kk++;
    }
    if(pp->next==NULL)
    {
         printf("位置(%d)不合法,超过了表长。\n",ii);
         return 0;
    }
    LNode *tmp=pp->next;
    pp->next=tmp->next;
    free(tmp);
    return 1;


}
int  PushFront(LinkList LL, ElemType *ee)
{
  return InsertList(LL,1,ee);
}

int PushBack(LinkList LL, ElemType *ee)
{
    return InsertList(LL,LengthList(LL)+1,ee);
}

int PopFront(LinkList LL)
{
  return DeleteNode(LL, 1);
}

int PopBack(LinkList LL)
{
    return DeleteNode(LL,LengthList(LL));
}

void PrintList(LinkList LL)
{
    if(LL==NULL)
    {
        printf("链表不存在\n");
        return;

    }

    LNode *tmp=LL->next;
    while(tmp!=NULL)
    {
        printf("%-3d",tmp->data);
        tmp=tmp->next;
    }
    printf("\n");
}

int  LengthList(LinkList LL)
{
  if (LL == NULL) { printf("链表LL不存在。\n"); return 0; } // 判断链表是否存在。

  LNode *pp=LL->next;  // 头结点不算,从第1个结点开始。

  int length=0;

  while (pp != NULL) { pp=pp->next; length++; }

  return length;

/*递归写法
if(LL==NULL)
    return 0;
return LengthList(LL->next)+1;
}
*/
}

void DestroyList(LinkList LL)//需要在主函数中写入LL=NULL;
{
    LNode * tmp;
    while(LL!=NULL)
    {
        tmp=LL->next;
        free(LL);//不保留LL的空间
        LL=tmp;
    }

}

void ClearList(LinkList LL)
{
    LNode *tmp1;
    LNode *tmp2;
    tmp1=LL->next;
    while(tmp1!=NULL)
    {
        tmp2=tmp1->next;
        free(tmp1);
        tmp1=tmp2;
    }
    LL->next=NULL;

}



int IsEmpty(LinkList LL)
{
    if(LL==NULL)
    {
        printf("链表不存在\n");
        return 0;
    }
    if(LL->next==NULL)
    {
        return 1;
    }
    return 0;
}

LNode *LocateNode(LinkList LL,unsigned int ii)
{
    if(LL==NULL)
    {
        printf("链表不存在\n");
        return NULL;
    }
    if((ii<0)&&(ii>LengthList(LL)))
    {
        printf("位置ii不合法\n");
        return 0;
    }
    LNode *tmp=LL;
    int kk=0;
    while(kk<ii)
    {
        tmp=tmp->next;
        kk++;
    }
    return tmp;

}

LNode*LocateElem(LinkList LL,ElemType *ee)
{
    if(LL==NULL)
    {
        printf("链表不存在\n");
        return NULL;
    }
    LNode*tmp=LL->next;
    while(tmp!=NULL)
    {
        if(tmp->data==*ee)
        return tmp;
        tmp=tmp->next;

    }
    return NULL;
}

int InsertNextNode(LNode*tmp,ElemType *ee)
{
    if(tmp==NULL)
    {
        printf("结点不存在\n");
        return 0;
    }if(tmp==NULL)
    {
        printf("结点不存在");
        return 0;
    }
    if(ee==NULL)
    {
        printf("元素ee不存在");
        return 0;
    }
    if(ee==NULL)
    {
        printf("元素ee不存在\n");
        return 0;
    }
    LNode*pp=tmp->next;
    LNode*qq=(LNode*)malloc(sizeof(LNode));
    if(qq==NULL)
    return 0;
    memcpy(&qq->data,ee,sizeof(ElemType));
    tmp->next=qq;
    qq->next=pp;
    return 1;

}

int InsertPriorNode(LNode*tmp,ElemType *ee)
{
    if(tmp==NULL)
    {
        printf("结点不存在\n");
        return 0;
    }
    if(ee==NULL)
    {
        printf("元素ee不存在\n");
        return 0;
    }
    LNode *copy=(LNode*)malloc(sizeof(LNode));//结构体含有指针变量时,不可以采用copy=tmp这样的方法;
    memcpy(&copy->data,&tmp->data,sizeof(ElemType));
    copy->next=tmp->next;
    memcpy(&tmp->data,ee,sizeof(ElemType));
    tmp->next=copy;
    return 1;
}

int DeleteNode1(LinkList LL,LNode*pp)
{
    if(pp==NULL)
    {
        printf("结点pp不存在\n");
        return 0;
    }
    LNode*tmp=LL->next;

    LNode*qq=LL;
    while(tmp!=NULL)
    {
        if(pp==tmp)
        {
            qq->next=tmp->next;
            free(tmp);

            tmp->next=NULL;
            return 1;
        }
        tmp=tmp->next;
        qq=qq->next;

    }
    return 1;
}

void ReverseList(LNode *pp)
{
    if(pp==NULL)
    {
        printf("结点PP不存在哦\n");
        return;
    }
    LNode *ss=pp->next;
    LNode *ssn;
    pp->next=NULL;
    while(ss!=NULL)
    {
        ssn=ss->next;
        ss->next=pp->next;
        pp->next=ss;
        ss=ssn;
    }

}


LNode* MergeList(LinkList La,LinkList Lb)
{
    if((La==NULL)||(Lb==NULL))
    {
        printf("链表La或链表Lb不存在\n");
        return NULL;
    }
    LNode*tmp;
    LinkList Lc;
    Lc=NULL;
    Lc=InitList();
    LNode* start=Lc;
    La=La->next;
    Lb=Lb->next;


    while((La!=NULL)&&(Lb!=NULL))
    {
        if(La->data<=Lb->data)
        {
            tmp=La;
            La=La->next;

        }
        else{
            tmp=Lb;
            Lb=Lb->next;


        }
        Lc->next=(LNode*)malloc(sizeof(LNode));
        Lc=Lc->next;
        memcpy(&Lc->data,&tmp->data,sizeof(ElemType));
        Lc->next=NULL;


    }
    while(La!=NULL)
    {
        Lc->next=(LNode*)malloc(sizeof(LNode));
        Lc=Lc->next;
        memcpy(&Lc->data,&La->data,sizeof(ElemType));
        Lc->next=NULL;
        La=La->next;

    }
    while (Lb != NULL)
    {
        Lc->next=(LNode *)malloc(sizeof(LNode));  // 分配一个新结点。
        Lc=Lc->next;
        memcpy(&Lc->data,&Lb->data,sizeof(ElemType));
        Lc->next=NULL;
        Lb=Lb->next;
    }
    return start;

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值