单链表源码实现

1、单链表的基本概念
在链式结构中,除了要存储数据元素的信息外,还要存储它的后继元素的存储地址。因此,为了表示每个数据元素ai与其直接后继元素ai+1之间的逻辑关系,对数据ai来说,除了存储其本身的信息之外,还需要存储一个指示其直接后继的信息(即直接后继的存储位置)。我们吧把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称做指针或链。这两部分信息组成数据元素ai的存储映像,称为结点(Node)。
n个结点(ai的存储映像)链结成一个链表,即为线性表(a1, a2, …, an)的链式存储结构,因为此链表的每个结点中只包含一个指针域,所以叫做单链表。


把链表中第一个结点的存储位置叫做头指针。

有时为了方便对链表进行操作,会在单链表的第一个结点前附设一个节点,称为头结点,此时头指针指向的结点就是头结点。

空链表,头结点的直接后继为空。

假设p是指向线性表第i个数据元素的指针,p->data表示第i个位置的数据域,p->next表示第i+1个位置的指针域,则第p+i个数据元素可表示为:

#include<stdio.h>
#include<stdlib.h>
#define maxlen 100	//数据最大长度 maxlen
#define ok 1	//操作成功标识 ok
#define no -1	//操作失败标识 no
typedef int Elemtype;	//Elemtype是数据的类型
typedef int cz;	//cz为执行操作时函数的类型

typedef struct Node{	//构造结点Node
	Elemtype data;		//存储数据
	struct Node *next;	//指向下一个结点
}Node;

typedef struct{	//构造单链表的结构LinkNode
	int len;	//len是表的长度
	Node *next;
}*Linklist;

cz Initlist(Linklist *L)	//初始化单链表表(有头结点)
{
	Linklist p=(Linklist)malloc(sizeof(Linklist)*maxlen);	//头指针
	Node *q=(Node *)malloc(sizeof(Node));	//头结点
	q->next=NULL;	//头结点后继指向NULL
	p->next=q;	//头指针指向头结点
	p->len=0;
	(*L)=p;
	return ok;
}

cz Listinsert(Linklist *L,int n,Elemtype e)	//插入 在第n位插入e元素
{
	if(n>(*L)->len+1||n<1){	//判断i是否符合条件
		return no;
	}
	Node *p=(*L)->next;	//指向头结点
	for(int i=1;i<n;i++)	//找到第i位的前结点
	{
		p=p->next;	//p指向第i位的前结点
	}
	Node *q=(Node *)malloc(sizeof(Node));	//生成一个新的结点
	q->data=e;
	q->next=p->next;	//先把q的后继结点连接到p->next
	p->next=q;	//再把q连接到p的后继结点上
	(*L)->len++;	//长度加1
	return ok;
}

cz Listdel(Linklist *L, int n)	//删除第n位元素
{
    if((*L)->len==0||n<1||n>(*L)->len){	//判断n是否符合条件且L长度不为1
        return no;
    }
    Node *p=(*L)->next;	//指向头结点
    Node *q;	//用来指向第n位结点
	for(int i=1;i<n;i++)	//找到第n位的前结点
	{
		p=p->next;	//p指向第n位的前结点即n-1位
	}
	q=p->next;
	p->next=q->next;	//第n-1位指向第n+1位
	free(q);	//释放空间
    (*L)->len--;    //长度减1
    return ok;
}

cz Getelem(Linklist L, int n, Elemtype *e)	//获取第n位元素的值并把其传给e
{
    if(n<1||n>L->len){	//判断n是否符合条件且L长度不为1
        return no;
    }
    Node *p=L->next;	//指向头结点
    for(int i=1;i<n+1;i++)	//找到第n位结点
	{
		p=p->next;	//p指向第n位结点
	}
	(*e)=p->data;//给值
    return ok;
}

void Output(Linklist L)	//遍历输出
{
    printf("当前链表表的长度:%d\n", L->len);
    Node *p=L->next->next;
    for(int i=0;i< L->len;i++){ 	//遍历整个L
        printf("%d	",p->data);
        p=p->next;    
    }
    printf("\n");
}

int main()
{
	Linklist *L;	//创建一个单链表表
	Initlist(L);	//初始化
	int i=1;
	int n;
	Elemtype e;
	printf("请输入数据:(当输入的值为-1时输入结束)\n");
	while(1){
		scanf("%d",&n);
		if(n== -1) break;
		e=(Elemtype)n;
		Listinsert(L,i,e);
		i++;
	}         
	printf("------------------------以上数据已插入表中-------------------------\n");
	printf("\n");
	printf("---------------------------遍历表中的数据---------------------------\n");
	Output(*L);
	printf("---------------------------删除表中的数据---------------------------\n");
	printf("请输入欲删除数据的位置:");
	scanf("%d",&n);
	Listdel(L,n);
	Output(*L);
	printf("---------------------------获取表中的数据---------------------------\n");
	Elemtype x;
	printf("请输入欲获取数据的位置:");
	scanf("%d",&n);
	Getelem(*L,n,&x);
	printf("第%d位元素的值为:%d\n",n,x);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值