结构体定义
typedef struct LNode
{
Elemtype data;
struct LNode *next;
}LNode, *LinkList;
初始化
带头结点的初始化
void InitList(LinkList L)
{
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
}
头指针的初始化
void InitList(LinkList &L)
{
L = NULL;
}
头插法建立单链表(头结点)
//头插法建立单链表
LinkList ListHeaderInsert(LinkList &L)
{
//Init List Start (头节点的建立)
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL; //头插法这一步很重要 尾插法不需要此步
//Init List End
int x;
LNode *s;
scanf("%d", &x);
while(x != 999)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
L->next = s;
scanf("%d", &x);
}
return L;
}
逆置链表
头结点
将头结点断开,再将结点按顺序头插回头结点
bool ReverList(LinkList &L)
{
if(L->next == NULL) //链表为空
return false;
LNode *p = L->next, *q;
L->next = NULL; //断开头结点
while(p != NULL) //将结点逐个头插回头结点即可逆置
{
q = p->next;
p->next = L->next;
L->next = p;
p = q;
}
return true;
}
头指针
将头指针断开,将其他结点逐一头插
bool ReverseList(LinkList &L)
{
if(L == NULL)
return false;
LNode *p = L->next, *q;
L->next = NULL; //断开头指针
while(p != NULL) //头插
{
q = p->next;
p->next = L;
L = p;
p = q;
}
return true;
}
尾插法建立单链表(头结点)
LinkList ListTailInsert(LinkList &L)
{
//Init List Start (头节点的建立)
L = (LinkList)malloc(sizeof(LNode));
//Init List End
int x;
LNode *r = L, *s;
scanf("%d", &x);
while(x != 999)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
scanf("%d", &x);
}
r->next = NULL; //尾插法这一步很重要,不然尾部指针异常
return L;
}
在第i个位置插入一个新结点
带头结点
bool ListInsert(LinkList L, int i, Elemtype e)
{
if(i < 1)
return false;
int j = 1;
LNode *p = L, *s;
while(p != NULL && j < i)
{
p = p->next;
j++;
}
if(p == NULL)
return false;
s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
头指针
bool ListInsert(LinkList &L, int i, Elemtype e)
{
if(i < 1)
return false;
int j = 1;
LNode *s, *p = L;
if(i == 1)
{
s = (LNode *)malloc(sizeof(LNode));
s->next = L;
s->data = e;
L = s;
}
else
{
while(p != NULL && j < i - 1)
{
p = p->next;
j++;
}
if(p == NULL)
return false;
s = (LNode *)malloc(sizeof(LNode));
s->next = p->next;
p->next = s;
s->data = e;
}
return true;
}
删除第i个位置的结点
带头结点
bool ListDelete(LinkList L, int i, Elemtype &e)
{
if(i < 1)
return false;
int j = 1;
LNode *p = L, *q;
while(p != NULL && j < i)
{
p = p->next;
j++;
}
if(p == NULL)
return false;
if(p->next == NULL)
return false;
q = p->next;
e = q->data;
p->next = q->next;
free(q);
return true;
}
头指针
bool ListDelete(LinkList &L, int i)
{
if(L == NULL || i < 1)
return false;
LNode *p = L, *q;
int j = 1;
if(i == 1)
{
L = L->next;
free(p);
return true;
}
while(p != NULL && j < i - 1)
{
p = p->next;
j++;
}
if(p == NULL || p->next == NULL)
return false;
q = p->next;
p->next = q->next;
free(q);
return true;
}
指定结点前插入一个结点
可以通过在指定结点后插入一个新结点,并对两个结点的值进行互换
bool InsertPriorNode(LNode *p, Elemtype e)
{
if(p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if(s == NULL)
return false;
s->data = p->data;
s->next = p->next;
p->next = s;
p->data = e;
return true;
}
删除指定结点的结点
可以将下个结点的值赋予指定删除的结点,删除下一个结点。 边界情况:当指定结点位于表尾巴时,下一个结点为NULL,会导致空指针异常
bool DeleteNode(LNode *p)
{
if(p == NULL)
return false;
if(p->next == NULL) //排除边界情况
return false;
LNode *q = p->next;
p->data = q->data;
p->next = q->next;
free(q);
return true;
}
按值查找
LNode *LocateElem(LinkList L, Elemtype e)
{
LNode *p = L->next; //若使用头指针 p = L
while(p != NULL && p->data != e)
p = p->next;
return p;
}
按位查找(位序)
LNode *GetElem(LinkList L, int i)
{
if(i < 0)
return NULL;
int j = 0;
LNode *p = L;
while(p != NULL && j < i) //头指针: while(p != NULL && j < i - 1)
{
p = p->next;
j++;
}
return p;
}
长度
int Length(LinkList L)
{
LNode *p = L;
int len = 0;
while(p->next != NULL) //头指针 while(p != NULL)
{
p = p->next;
len++;
}
return len;
}