单链表(不带头结点)的基本操作

       相对于带头结点的单链表对每一个结点的操作比较统一,不带头结点的单链表需要对第一个结点进行特殊的对比操作。

1、操作实现

1.1单链表的定义

通过结构体定义每个结点的数据格式

typedef int ElemType;//元素的类型

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

1.2初始化单链表

通过对单链表之间设置为空完成初始化

//初始化单链表
void InitList(LinkList &L)
{
	L = NULL;
}

1.3得到单链表表长

通过遍历实现获得单链表表长,如果第一个结点就为空则返回0

//得到表长
int Length(LinkList L)
{
	int length = 0;
	if(L == NULL)//首先判断第一个结点是否为空
		return length;
	else
		length++;
	while(L->next != NULL)
	{
		length++;
		L = L->next;
	}
	return length;
}

1.4单链表的判空操作

通过判断第一个结点是否为空,判断单链表是否为空

//判断的单链表是否为空表
bool Empty(LinkList L)
{
	if(L == NULL)
		return true;
	else
		return false;
}

1.5建立单链表

建立单链表分头插法和尾插法两种方式

1.5.1头插法

每次插入都在表头的位置

//头插法建立单链表
LinkList List_HeadInsert(LinkList &L)
{
	InitList(L);//初始化
	LNode *s;
	ElemType e;
	printf("输入元素(输入9999为停止)");
	scanf("%d",&e);
	if(e != 9999)//首先对第一个结点赋值
	{
		L = (LinkList)malloc(sizeof(LNode));
		L->next = NULL;
		L->data = e;
		scanf("%d",&e);
		while(e != 9999){
			s = (LNode*)malloc(sizeof(LNode));
			s->data = e;
			s->next = L->next;
			L->next = s;
			scanf("%d",&e);
		}
	}
	return L;
}

1.5.2尾插法

每次插入都在表尾的位置

//尾插法建立单链表
LinkList List_TailInsert(LinkList &L)
{
	InitList(L);//初始化
	LNode *s,*r;
	ElemType e;
	printf("输入元素(输入9999为停止)");
	scanf("%d",&e);
	if(e != 9999)//首先对第一个结点赋值
	{
		L = (LinkList)malloc(sizeof(LNode));
		L->data = e;
		r = L;
		scanf("%d",&e);
		while(e != 9999)
		{
			s = (LNode*)malloc(sizeof(LNode));
			s->data = e;
			r->next = s;
			r = s;
			scanf("%d",&e);
		}
	}
	r->next = NULL;
	return L;
}

1.6按值查找结点

1.6.1得到一个结点

//在表中查找第一个与查找元素相同位置的结点
LNode* LocateElem_LNode(LinkList L, ElemType e)
{
	int j = 1;
	LNode* p = L;
	if(p->data == e)//首先查看第一个结点
		return p;
	else
		p = p->next;
	while(p != NULL && p->data != e)
	{
		p = p->next;
		j++;
	}
	if(j == Length(L))
	{
		return NULL;
	}
	return p;
}

1.6.2得到该结点的位置

int LocatedElem(LinkList L, ElemType e)
{
	int j = 1;
	LNode* p = L;
	if(p->data == e)
		return j;
	else
		p = p->next;
	while(p != NULL && p->data != e)
	{
		p = p->next;
		j++;
	}
	if(j == Length(L))//到最后一位依然没找到
	{
		return 0;
	}
	return j+1;
}

1.7按位查找结点

1.7.1得到一个结点

//得到表中某一位置的结点
LNode* GetElem_LNode(LinkList L, int i)
{
	LNode *p = L;
	if(i < 0 || i > Length(L))
		return NULL;
	for(int j = 1; j < i; j++)
	{
		p = p->next;
	}
	return p;
}

1.7.2得到该位置结点的数据

//获得某一位置元素的值
ElemType GetElem(LinkList L, int i)
{
	LNode *p = L;
	if(i < 0 || i > Length(L))
		return 0;
	for(int j = 1; j < i; j++)
	{
		p = p->next;
	}
	return p->data;
}

1.8插入数据

向表中对应位置插入数据

//向表中插入数据
bool ListInsert(LinkList &L, int i, ElemType e)
{
	if(i < 1 || i > Length(L)+1)
		return false;
	LNode *s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	if(i == 1)
	{
		s->next = L;
		L = s;
		return true;
	}
	LNode *p = GetElem_LNode(L,i-1);
	s->next = p->next;
	p->next = s;
	return true;
}

1.9删除数据

删除表中某一位置的数据

//删除表中某位置的数据
bool ListDelete(LinkList &L, int i, ElemType &e)
{
	if(i < 1 || i > Length(L))//位置不在表中则返回false
		return false;
	if(L == NULL)//表为空则返回false
		return false;
	LNode* p;
	LNode* q;
	if(i == 1)//删除第一个结点的情况
	{
		p = L;
		e = p->data;
		q = L->next;
		free(p);//释放p结点
		L = q;
		return true;
	}
	p = GetElem_LNode(L,i-1);
	q = p->next;
	e = q->data;
	p->next = q->next;
	free(q);
	return true;
}

1.10输出表中数据

通过遍历的方式打印表中数据

//打印单链表的所有数据
void PrintList(LinkList L)
{
	printf("表中的数据为:");
	if(L != NULL)
	{
		printf("%d ",L->data);
		while(L->next != NULL)
		{
			L = L->next;
			printf("%d ",L->data);
		}
	}
	printf("\n");
}

1.11清空表

删除表中所有数据

//清空表的数据
bool ClearList(LinkList &L)
{
	if(L == NULL)//表空则返回false
		return false;
	LNode *p;
	while(L->next != NULL)//删除第一个结点之后的所有结点
	{
		p = L->next;
		L->next = p->next;
		free(p);
	}
	L = NULL;//删除第一个结点
	return true;
}

2、全部代码

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

typedef int ElemType;//元素的类型

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

//初始化单链表
void InitList(LinkList &L)
{
	L = NULL;
}

//得到表长
int Length(LinkList L)
{
	int length = 0;
	if(L == NULL)//首先判断第一个结点是否为空
		return length;
	else
		length++;
	while(L->next != NULL)
	{
		length++;
		L = L->next;
	}
	return length;
}

//判断的单链表是否为空表
bool Empty(LinkList L)
{
	if(L == NULL)
		return true;
	else
		return false;
}

//头插法建立单链表
LinkList List_HeadInsert(LinkList &L)
{
	InitList(L);//初始化
	LNode *s;
	ElemType e;
	printf("输入元素(输入9999为停止)");
	scanf("%d",&e);
	if(e != 9999)//首先对第一个结点赋值
	{
		L = (LinkList)malloc(sizeof(LNode));
		L->next = NULL;
		L->data = e;
		scanf("%d",&e);
		while(e != 9999){
			s = (LNode*)malloc(sizeof(LNode));
			s->data = e;
			s->next = L->next;
			L->next = s;
			scanf("%d",&e);
		}
	}
	return L;
}

//尾插法建立单链表
LinkList List_TailInsert(LinkList &L)
{
	InitList(L);//初始化
	LNode *s,*r;
	ElemType e;
	printf("输入元素(输入9999为停止)");
	scanf("%d",&e);
	if(e != 9999)//首先对第一个结点赋值
	{
		L = (LinkList)malloc(sizeof(LNode));
		L->data = e;
		r = L;
		scanf("%d",&e);
		while(e != 9999)
		{
			s = (LNode*)malloc(sizeof(LNode));
			s->data = e;
			r->next = s;
			r = s;
			scanf("%d",&e);
		}
	}
	r->next = NULL;
	return L;
}

//在表中查找第一个与查找元素相同位置的结点
LNode* LocateElem_LNode(LinkList L, ElemType e)
{
	int j = 1;
	LNode* p = L;
	if(p->data == e)//首先查看第一个结点
		return p;
	else
		p = p->next;
	while(p != NULL && p->data != e)
	{
		p = p->next;
		j++;
	}
	if(j == Length(L))
	{
		return NULL;
	}
	return p;
}
//在表中查找第一个与查找元素相同的结点的位置
int LocatedElem(LinkList L, ElemType e)
{
	int j = 1;
	LNode* p = L;
	if(p->data == e)
		return j;
	else
		p = p->next;
	while(p != NULL && p->data != e)
	{
		p = p->next;
		j++;
	}
	if(j == Length(L))//到最后一位依然没找到
	{
		return 0;
	}
	return j+1;
}

//得到表中某一位置的结点
LNode* GetElem_LNode(LinkList L, int i)
{
	LNode *p = L;
	if(i < 0 || i > Length(L))
		return NULL;
	for(int j = 1; j < i; j++)
	{
		p = p->next;
	}
	return p;
}
//获得某一位置元素的值
ElemType GetElem(LinkList L, int i)
{
	LNode *p = L;
	if(i < 0 || i > Length(L))
		return 0;
	for(int j = 1; j < i; j++)
	{
		p = p->next;
	}
	return p->data;
}

//向表中插入数据
bool ListInsert(LinkList &L, int i, ElemType e)
{
	if(i < 1 || i > Length(L)+1)
		return false;
	LNode *s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	if(i == 1)
	{
		s->next = L;
		L = s;
		return true;
	}
	LNode *p = GetElem_LNode(L,i-1);
	s->next = p->next;
	p->next = s;
	return true;
}

//删除表中某位置的数据
bool ListDelete(LinkList &L, int i, ElemType &e)
{
	if(i < 1 || i > Length(L))//位置不在表中则返回false
		return false;
	if(L == NULL)//表为空则返回false
		return false;
	LNode* p;
	LNode* q;
	if(i == 1)//删除第一个结点的情况
	{
		p = L;
		e = p->data;
		q = L->next;
		free(p);//释放p结点
		L = q;
		return true;
	}
	p = GetElem_LNode(L,i-1);
	q = p->next;
	e = q->data;
	p->next = q->next;
	free(q);
	return true;
}

//打印单链表的所有数据
void PrintList(LinkList L)
{
	printf("表中的数据为:");
	if(L != NULL)
	{
		printf("%d ",L->data);
		while(L->next != NULL)
		{
			L = L->next;
			printf("%d ",L->data);
		}
	}
	printf("\n");
}

//清空表的数据
bool ClearList(LinkList &L)
{
	if(L == NULL)//表空则返回false
		return false;
	LNode *p;
	while(L->next != NULL)//删除第一个结点之后的所有结点
	{
		p = L->next;
		L->next = p->next;
		free(p);
	}
	L = NULL;//删除第一个结点
	return true;
}

int main()
{
	LinkList L;
	LNode* p;
	ElemType e;
	InitList(L);
	if(Empty(L))//判空
		printf("表是空表\n");
	else
		printf("表不是空表\n");
	List_TailInsert(L);//尾插法
	PrintList(L);
	printf("表长为%d\n",Length(L));
	p = LocateElem_LNode(L,2);
	printf("6的位置%d\n",LocatedElem(L,6));
	printf("2号位置的数据%d\n",GetElem(L,2));
	ListInsert(L,2,3);//在第2号位置插入数据3
	printf("插入后的数据为");
	PrintList(L);
	ListDelete(L,1,e);//删除一号位置的数据
	printf("删除的元素为%d\n",e);
	printf("删除后的数据为");
	PrintList(L);
	ClearList(L);//清空表
	if(Empty(L))//清空之后判空
		printf("表是空表\n");
	else
		printf("表不是空表\n");
	return 0;
}
  • 51
    点赞
  • 213
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值