单链表定义:它是通过一组任意的存储单元来存储线性表中的数据元素,为了建立数据元素之间的线性关系对每个链表结点,除存放元素本身的信息外。还需要存放一个指向期,后继节点的指针。
数据描述:
typedef struct LNode{
ElemType data;//数据域
struct LNode *next;//指针域
}LNode,*LinkList;
//struct LNode *p =(struct LNode*)malloc(sizeof(struct LNode))增加一个新的节点,在内存中申请一个节点所需空间,并用指针P指向这个节点。
//LNode *L声明一个指向单链表,第1个节点的指针。LNode *强调返回的是一个节点。
//LinkList L声明一个指向单链表,第1个节点的指针。LinkList 强调这是一个单链表。
不带头结点的单链表的操作:
1初始化单链表:
//初始化单链表
void InitList(LinkList &L)
{
L = NULL;
}
2计算单链表的表长:
int Length(LinkList L)
{
int length = 0;
if(L == NULL)//首先判断第一个结点是否为空
return length;
else
length++;
while(L->next != NULL)
{
length++;
L = L->next;
}
return length;
}
3单链表的判断是否为空操作:
bool Empty(LinkList L)
{
if(L == NULL)
return true;
else
return false;
}
4建立单链表 :
4.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;
}
4.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;
}
尾插法用到两个指针,而头插法只用到一个指针。头插法的表头指针一直在进行工作。
5查找
5.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;
}
5.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;
}
5.3得到该位置结点的数据
//获得某一位置元素的值
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;
}
6插入数据:
/向表中插入数据
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;
}
7删除数据:删除表中某一位置的数据
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;
}
8输出表中数据:
//打印单链表的所有数据
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");
}
9清空表:
//清空表的数据
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;
}