单链表c语言实现

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

// 线性链表

typedef int ElemType; // 任意数据类型
typedef int Status;   // 函数返回数据类型

// 单链表
typedef struct LNode {
    ElemType data;      // 当前结点数据原色
    struct LNode *next; // 后一个结点指针
}LNode, *LinkList;

// 获得对应位置的元素
Status GetELem(LinkList L, int i, ElemType *e){
    // 获得第一个元素指针
    LNode *p = L->next;
    // 记录当前位置
    int j = 1;
    // 循环找到对应位置的地址
    while(p && j<i){
        p = p->next;
        ++j;
    }
    // 判断跳出while循环的原因,是否是查找到了需要的元素,即p指向的元素是否为空 或者 j是否大于i
    if(!p || j>i) return 0;
    // 存储需要的数据元素
    *e=p->data;
    return 1;
}

// 在指定位置插入指定元素
Status InsertElem(LinkList L, int i, ElemType e){
    // 获得第一个数据元素的结点位置
    LNode *p = L->next;
    int j=1;
    // 循环至i位置元素的前一个元素,因为只有找到前一个位置的元素,才能将第i个元素替换掉
    for(; p&&j<i-1; j++)
        p = p->next;
    if(!p||j>i-1) return 0;
    // 申请新的结点内存
    LNode *newN = (LNode *)malloc(sizeof(LNode));
    newN->data = e;
    newN->next = p->next;
    // 将i位置的地址替换成新地址
    p->next = newN;
    return 1;
}

// 删除对应位置的数据元素
Status DelElem(LinkList L,int i, ElemType *e){
    // 前面和插入差不多
    LNode *p = L->next;
    int j=1;
    for(; p&&j<i-1; j++)
        p = p->next;
    // 删除要看后面的后面是否超过长度,所以看后面一个是否为空
    if(!(p->next)||j>i-1) return 0;
    // 存储一下删除的位置,为了之后的释放结点
    LNode *q = p->next;
    *e = q->data;
    p->next = p->next->next;
    // 释放结点
    free(q);
}

// 将两个有序列表合并为一个有序列表
void Merge(LinkList a, LinkList b, LinkList c){
    LNode *pa, *pb, *pc;
    pa = a->next; pb = b->next; pc = c = a;

    while (pa && pb){
        if(pa->data <= pb->data){
            // pc->next=pa, 将pa接到pc后面; pc=pa相当于pc=pc->next; 然后将pa后移
            pc->next = pa; pc = pa; pa = pa->next;
        }else{
            pc->next = pb; pc = pb; pb = pb->next;
        }
    }
    // 将未为空的链表链接到最后
    pc->next = pa?pa:pb;
    // 释放b头结点空间
    free(b);
}


// 初始化链表
LinkList InitList(){
	LinkList l = (LinkList)malloc(sizeof(LNode)); // 用malloc给链表分配空间
	l->next = NULL;	// 初始化时,把next指向空
	return l;
}

//创建链表---头插法
void CreateListHead(LinkList L, int n){
    for(int i=n;i>0;--i){
        // 申请一个结点的地址空间
        LNode *p = (LNode*)malloc(sizeof(LNode));
        // 存储输入的数据元素
        scanf("%d",&p->data);
        // 新结点的后一个节点指针存储为L的第一个数据元素位置指针
        p->next = L->next;
        // 将L的第一个数据元素位置指针指向p
        L->next = p;
    }
}

//创建链表---尾插法
void CreateListEnd(LinkList L, int n){
	LNode *end;
	// end指针指向L的头结点
	end = L;
	for(int i=0; i<n; i++){
        // 若end当前指向的不是L结尾,循环指向结尾
		while (end->next != NULL)
            end = end->next;
        // 申请一个结点的地址空间
        LNode *p = (LinkList)malloc(sizeof(LinkList));
        scanf("%d", &p->data);
        p->next = NULL;
        // 将结尾指针指向新的结点地址
        end->next = p;
	}
}

//输出单链表
void Display(LinkList L){
    // 获得第一个结点地址
    LNode *p = L->next;
    printf("单链表的内容为:");
    // 循环输出数据元素值
    while(p){
        printf("%d",p->data);
        if(p->next) printf("->");
        else printf("\n");
        p = p->next;
    }
}

int main()
{
    LinkList l;
    l = InitList();
    printf("请输入链表长度:");
    int n,k;
    scanf("%d",&n);
    printf("请选择插入方式(1 头插法  2 尾插法):");
    scanf("%d",&k);
    printf("请输入数据:\n");
    if(k == 1)
        CreateListHead(l, n);
    else
        CreateListEnd(l, n);
    Display(l);
    ElemType e;
    GetELem(l,1,&e);
    printf("%d\n",e);

    printf("请输入插入元素和插入位置(以空格分隔):");
    scanf("%d %d",&e,&k);
    if(InsertElem(l,k,e) == 0)
        printf("输入不合法!\n");
    else
        Display(l);

    printf("请输入删除位置:");
    scanf("%d",&k);
    if(DelElem(l,k,&e) == 0)
        printf("输入不合法!\n");
    else{
        printf("删除的元素为:%d\n",e);
        Display(l);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值