数据结构-----------单链表定义以及基本操作

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

typedef int ElemType;      //int类型改别名为ElemType
typedef struct LNode      //单链表的定义
{
    /* data */
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

/*                                   初始化操作                                                    */
int InitList(LinkList *L)   //带头结点的单链表初始化
{
    (*L) = (LNode *)malloc(sizeof(LNode));
    if(*L == NULL)
        return -1;     //内存分配失败
    (*L)->next = NULL;
    return 1;
}

/*                                    链表输出                                                    */
//输出单链表
void DispList(LinkList L)
{
    LNode *p = L->next;
    if (p == NULL)
    {
        printf("该链表为空");
    }
    while (p!=NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
    

}

/*                                  判空操作                                                           */
//判断是否为空表
int isEmptyList(LinkList L)
{
    if ((L->next) == NULL)
    {
        return -1;
    }else{
        return 1;
    }
    
}

/*                                   销毁操作                                                        */
//销毁单链表
int DestoryLinkList(LinkList *L)
{
    LNode* p;
    while (*L)
    {
        p = *L;
        (*L) = (*L)->next;
        free(p);
    }
    return 1;
}
/*                                    求表长                                                */
//求表长
int LinkListLen(LinkList L)
{
    int length = 0;
    while (L->next != NULL)
    {
        length++;
        L = L->next;
    }
    return length;
}

/*                                    建表操作                                                 */
//头插法建立单链表
int CreateList_HeaderInsert(LinkList *L,int n)
{
    *L = (LinkList)malloc(sizeof(LNode)); //头节点
    if(*L==NULL)
        return -1;//分配内存失败
    (*L)->next = NULL;
    int i=0;
    int k=0;
    for(i=0;i<n;i++)
    {   
        LNode *p = (LNode *)malloc(sizeof(LNode));
        if (p = NULL)
            return -1;
        scanf("%d",&k);
        p->data = k;
        p->next = (*L)->next;
        (*L)->next = p;
    }
}

//尾插法建表
int CreateList_TailerInsert(LinkList *L,int n)
{
    (*L) = (LinkList)malloc(sizeof(LNode));  //头节点
    if((*L)==NULL)
        return -1;  //内存分配失败
    int i=0;
    int k=0;
    LNode *r = (*L);
    for (i=0;i<n;i++)
    {
        LNode *s = (LNode *)malloc(sizeof(LNode));
        scanf("%d",&k);
        s->data = k;
        r->next = s;
        r = s;   //更新尾指针
    }
    r->next = NULL;  //尾指针置空
    return 1;
}

/*                                      查询操作                                                   */
//按位取值--------按位查找
int GetElem(LinkList L,int i,int *e)
{
    if(i<1)
        return -1;  //位置不合法
    LNode* p = L->next;
    int count=1;
    while (p!=NULL && count<i)
    {
        p = p->next;
        count++;
    }
    if (p==NULL || count>i)
    {
        return -1;
    }else{
        *e = p->data;
        return 1;
    }
}

//按值查找
int LocateElem(LinkList L,int num)
{
    int count = 1;
    LNode *p = L->next;
    while (p!=NULL && p->data!=num)
    {
        p = p->next;
        count++;
    }
    if (p == NULL)
        return -1;
    else{
        return count;
    }
    
}

/*                                  删除操作                                          */
//按位序删除-----删除位序为i的节点-------先找到它的前驱节点也就是i-1节点
int DeleteByPostion(LinkList *L,int i,int *e)
{
    if (i<1)
        return -1; //位置不合法

    LNode *p = (*L);
    int j = 0;

    while (p!=NULL && j<i-1)  //找到第i-1个位置
    {
        p = p->next;
        j++;
    }
    if (p==NULL)
        return -1;  //位置不合法
    if (p->next==NULL)
        return -1;  //i-1之后无其他节点
    LNode *q = p->next;
    *e = q->data;
    p->next = q->next;
    free(q);
    return 1;
}


//按值删除
int DeleteByValue(LinkList *L,int num)
{
    LNode *p = (*L);
    LNode *prev = NULL;
    while (p!=NULL && p->data!=num)
    {
        prev = p;
        p = p->next;
    }
    if (p == NULL)
        return -1;//链表中查无此值
    if (prev == NULL)  //表明要删除的是头节点
    {
        (*L) = p->next;
        free(p);
    }else{
        prev->next = p->next;  //不是头节点的情况
        free(p);
    }
    return 1;
}

/*                                 插入操作                        */
//指定节点后插操作 ---------------在节点p之后插入元素e
int InsertNextNode(LNode *p,int e)
{
    if (p==NULL)
        return -1;
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if (s==NULL)
    {
        return -1;  //内存分配失败
    }
    s->data = e;
    p->next = s->next;
    p->next = s;
    return 1;
}

//指定节点前插操作---------------在节点p之前插入元素e
int InsertPriorNode(LNode *p,int e)
{
    if (p==NULL)
        return -1;
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if (s==NULL)
        return -1; //内存分配失败
    s->next = p->next;  //s 接在 p 之后
    p->next = s;
    s->data = p->data;  // s p 的值互换
    p->data = e;
    return 1;
}

//按位序插入-----找到i-1号节点并进行后插操作
int InsertListBySeq(LinkList *L,int i,int e)
{
    if (i<1)
        return -1; // 位置非法
    LNode *p = (*L);
    int j = 0;
    while (p != NULL && j<i-1) // 找到i-1 个位置然后进行后插
    {
        p = p->next;
        j++;
    }
    if (p == NULL)
        return -1;   //位置非法

    //后插操作     InsertNextNode(LNode *p,int e)
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return 1;
}

//按位序插入----------找到i号节点并进行前插操作
int InsertListBySeq2(LinkList *L,int i,int e)
{
    if (i<1)
        return 1;//位置非法
    LNode *p = (*L);
    int j = 0;
    while (p != NULL && j<i) // 找到i号位置然后进行前插
    {
        p = p->next;
        j++;
    }
    if (p == NULL)
        return -1;   //位置非法
    //前插操作
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if (s==NULL)
        return -1;//内存分配失败

    //指定节点前插操作
    s->next = p->next;
    p->next = s;
    s->data = p->data;
    p->data = e;
    return 1;
}

//指定元素值前插入
int InsertHeadByItemValue(LinkList *L,int item,int Value)
{
    LNode *p = (*L);
    LNode *pre = NULL;
    while (p!=NULL && p->data!=item)
    {
        pre = p;
        p = p->next;
    }
    if (p == NULL)
        return -1;//链表查无此值
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if (s == NULL)
        return -1;//内存分配失败
    s->data = Value;
    s->next = p;
    if (pre == NULL)  //目标节点为头节点,则需要更新头节点
        (*L) = s;
    else
        pre->next = s; //将s接入原链表
    return 1;
}

//指定元素值后插入
int  InsertNextByItemValue(LinkList *L,int item,int Value)
{
    LNode *p = (*L);
    while (p!=NULL && p->data!=item)
    {
        p = p->next;
    }
    if (p == NULL)
        return -1;//单链表查无此值
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if (s==NULL)
        return -1;//内存分配失败
    s->data = Value;
    s->next = p->next;
    p->next = s;
    return 1;
}



int main()
{
    LinkList L;
    InitList(&L);
    int a = 0;
    //printf("你想要用几个元素使用头插法建表:\n");

    printf("你想要用几个元素使用尾插法建表:\n");
    
    scanf("%d",&a);

    //CreateList_HeaderInsert(&L,a);

    CreateList_TailerInsert(&L,a);
    
    printf("当前链表的元素为:");
    DispList(L);
    printf("\n");


    printf("该链表是否为空表:");
    int flag = 0;
    flag = isEmptyList(L);
    if (flag == -1)
    {
        printf("YES");
    }else{
        printf("NO");
    }
    printf("\n");

    int length = LinkListLen(L);
    printf("当前链表的长度为:%d",length);
    printf("\n");


    int position = 0;
    printf("请输入position:");
    scanf("%d",&position);
    int flag2 = 0;
    int e = 0;
    flag2 = GetElem(L,position,&e);
    if (flag2==-1)
    {
        printf("位置不合法");
    }else{
        printf("第%d位元素是%d",position,e);
    }
    printf("\n");


    printf("你想要查找的元素值为:");
    int num = 0;
    scanf("%d",&num);
    int flag3 = 0;
    flag3 = LocateElem(L,num);
    if (flag3 == -1)
    {
        printf("查找失败,链表中无此元素!");
    }else{
        printf("查找成功,该元素在链表中的序号为:%d",flag3);
    }
    printf("\n");
    

    printf("你想要删除的元素位序为:");
    int pos = 0;
    scanf("%d",&pos);
    int flag4 = 0;
    int e4 = 0;
    flag4 = DeleteByPostion(&L,pos,&e4);
    if (flag4==-1)
    {
        printf("删除失败,位置不合法!");
    }else{
        printf("删除成功,被删除的元素为%d\n",e4);
    }
    printf("删除之后的单链表为:");
    DispList(L);
    printf("\n");
    
    printf("你想要删除的元素值为");
    int ItemValue = 0;
    scanf("%d",&ItemValue);
    int flag5 = 0;
    flag5 = DeleteByValue(&L,ItemValue);
    if (flag5==-1)
        printf("删除失败,该链表中不存在此元素");
    if (flag5==1)
        printf("删除成功,删除该元素之后的链表为:");
    DispList(L);

    printf("按位序操作,在指定位序插入相应元素-----使用后插操作");
    int InsertBySeqPos = 0;
    printf("请输入你想插入的位置:\n");
    scanf("%d",&InsertBySeqPos);
    int InsertBySeqNum = 0;
    printf("请输入你想插入的值:\n");
    scanf("%d",&InsertBySeqNum);
    int flag6 = 0;
    flag6 = InsertListBySeq(&L,InsertBySeqPos,InsertBySeqNum);
    if (flag6 == -1)
        printf("插入失败,元素位置不合法");
    else{
        printf("插入成功");
        DispList(L);
    }
    printf("\n");

    printf("按位序操作,在指定位序插入相应元素--------使用前插操作");
    int InsertBySeqPos2 = 0;
    printf("请输入你想插入的位置:\n");
    scanf("%d",&InsertBySeqPos2);
    int InsertBySeqNum2 = 0; 
    printf("请输入你想插入的值:\n");
    scanf("%d",&InsertBySeqNum2);
    int flag7 = 0;
    flag7 = InsertListBySeq2(&L,InsertBySeqPos2,InsertBySeqNum2);
    if (flag7 == -1)
        printf("插入失败,元素位置不合法");
    else{
        printf("插入成功");
        DispList(L);
    }
    printf("\n");

    int Item = 0;
    int Value = 0;
    printf("请输入你想插入到哪个元素之前");
    scanf("%d",&Item);
    printf("请输入你想插入的元素值");
    scanf("%d",&Value);
    int flag8 = 0;
    flag8 = InsertHeadByItemValue(&L,Item,Value);
    if (flag8 == -1){
        printf("插入失败,单链表中无此值!");
    }else{
        printf("插入成功,插入之后的单链表为:");
        DispList(L);
    }
    printf("\n");

    int Item2 = 0;
    int Value2 = 0;
    printf("请输入你想插入到哪个元素之后");
    scanf("%d",&Item2);
    printf("请输入你想插入的元素值");
    scanf("%d",&Value2);
    int flag9 = 0;
    flag9 = InsertNextByItemValue(&L,Item2,Value2);
    if (flag9 == -1)
        printf("插入失败,链表中没有此元素!");
    else{
        printf("插入成功,插入后的链表为:");
        DispList(L);
    }
    DestoryLinkList(&L);
}

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值