目录
八、指定结点删除(删除指定结点p,思想是将p结点和其后面的结点互换)
一、单链表的定义
typedef struct Lnode//定义单链表的结点类型
{
ElemType data;//每个结点存放一个数据元素
struct Lnode* next;//指针指向下一个结点
}Lnode, * LinkList;
Lnode* L;//声明一个指向单链表第一个结点的指针
LinkList L;//声明一个指向单链表第一个结点的指针
注意:
强调这是一个单链表,使用LinkList
强调这是一个结点,使用Lnode*
二、单链表的初始化(实际是建立一个空的单链表)
1.不带头结点的单链表
bool InitList(LinkList & L)
{
L = NULL;
return true;
}
2.带头结点的单链表
{
L = (Lnode*)malloc(sizeof(Lnode));
if (L == NULL)
return false;//内存不足,分配失败
else
L->next = NULL;
return true;
}
补充:
判断单链表(无头结点)是否为空
bool Empty(LinkList L)
{
if (L == NULL)
return true;
else
return false;
}
判断单链表(有头结点)是否为空
bool Empty(LinkList L)
{
if (L->next == NULL)
return true;
else
return false;
}
三、单链表的建立(尾插和头插)
1.尾插法
LinkList List_Tailnsert(LinkList & L)
{
ElemType x;
L = (LinkList)malloc(sizeof(Lnode));//建立头结点
Lnode* s;
Lnode* tail = L;//tail为尾指针
cin >> x;
while (x != 999)
{
s = (Lnode*)malloc(sizeof(Lnode));
s->data = x;
tail->next = s;
tail = s;//tail指向新的表尾结点
cin >> x;
}
tail->next = NULL;//尾结点置空
return L;
}
2.头插法
LinkList List_HeadInsert(LinkList & L)
{
Lnode* s;
L = (LinkList)malloc(sizeof(Lnode));//创建头结点
L->next = NULL;//初始为空链表
ElemType x;
cin >> x;
while (x != 999)
{
s = (Lnode*)malloc(sizeof(Lnode));
s->data = x;
s->next = L->next;
L->next = s;//将新结点插入表中
cin >> x;
}
return L;
}
四、按照位序插入
1.带头结点
bool ListInsert(LinkList& L, int i, ElemType e)
{
if (i < 1)
return false;
Lnode* p;//指针p指向当前扫描到的结点
int j = 0;//当前p指向的是第几个结点
p = L;//L指向头结点,头结点是第0个结点(不存在数据)
while (p != NULL && j < i - 1)//循环找到第i-1个结点
{
p = p->next;
j++;
}
if (p == NULL)//此时p指向空(没有存放数据和指针),意味找完了都没有找到
{
return false;
}
else//找到了
{
Lnode* s = (Lnode*)malloc(sizeof(Lnode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
}
2.不带头结点
bool ListInsert(LinkList & L, int i, ElemType e)
{
if (i < 1)
return false;
if (i == 1)//插入第一个结点
{
Lnode* s = (Lnode*)malloc(sizeof(Lnode));
s->data = e;
s->next = L;
L = s;//头指针指向新的结点
return true;
}
Lnode* p;//指针p指向当前扫描到的结点
int j = 1;//当前p指向的第几个结点
p = L;
while (p1 = NULL && j < i - 1)
{
p = p->next;
j++;
}
if (p == NULL)
return false;
Lnode* s = (Lnode*)malloc(sizeof(Lnode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
五、指定结点的后插
bool InsertNextnode(Lnode* p, ElemType e)
{
if (p == NULL)
return false;
Lnode* s = (Lnode*)malloc(sizeof(Lnode));
if (s == NULL)//分配内存失败
return false;
s->data = e;
s->next = p->next;
p->next = s;//将结点s连到p之后
return true;
}
六、指定结点的前插(在p结点之前插入元素e)
bool InsertPriornode(Lnode* p, ElemType e)
{
if (p == NULL)
return false;
Lnode* s = (Lnode*)malloc(sizeof(Lnode));
if (s == NULL)
return false;
s->next = p->next;
p - next = s;//将新的结点连到p之后
s->data = p->data;//将p中元素复制到s中
p->data = e;//将p中元素覆盖为e
return true;
}
七、按位序删除(带头结点)思想:将p结点和后面结点互换
bool ListDelete(LinkList& L, int i, ElemType& e)
{
if (i < 1)
return false;
Lnode* p;//指针p指向当前扫描到的结点
int j = 0;
p = L;
while (p != NULL && j < i - 1)
{
p = p->next;
j++;
}
if (p == NULL)
return false;
if (p->next == NULL)//第i-1个结点之后再无其他结点
return false;
Lnode* q = p->next;
q->data = e;
p->next = q->next;//将*q结点从链中断开
free(q);
return true;
}
八、指定结点删除(删除指定结点p,思想是将p结点和其后面的结点互换)
bool Deletenode(Lnode* p)
{
if (p == NULL)
return false;
else if (p->next == NULL)//如果p为最后一个结点
{
Lnode* s;
s = L;
while (s->next->data!=p->data)
{
s = s->next;
}
s->next = NULL;
free(p);
return true;
}
else
Lnode* q = p->next;//q为p的后面一个结点
p->data = p->next->data;//将q中的数据放入p中
p->next = q->next;//将*q结点从链中断开
free(q);
return true;
}
九、按值查找
Lnode* LocateElem(LinkList L, ElemType e)
{
Lnode* p = L->next;
while (p != NULL && p->data != e)
{
p = p->next;
}
return p;
}
十、按位置查找
bool GetElem(LinkList L,int i, ElemType& e)
{
Lnode* p;
p = L;
int j = 0;
while (p != NULL && j < i )
{
p = p->next;
j++;
}
if (p == NULL || j > i)
return false;
e = p->data;
return true;
}
十一、求表长(带头结点)
int Length(LinkList L)
{
int len = 0;
Lnode* p = L;
while (p->next != NULL)
{
p = p->next;
len++;
}
return len;
}
十二、销毁(保留头结点,从第一个结点开始释放所有结点)
bool Destroylist(LinkList& L)
{
Lnode* p, * s;
s = L->next;
while (s)
{
p = s;
s = s->next;
free(p);
}
}
十三、销毁(销毁所有包括头结点)
bool Destroylist2(LinkList& L)
{
Lnode* p;
while (L)
{
p = L;
L = L->next;
free(p);
}
}