/* 线性表的链式存储结构 */
typedef int ElemType;
typedef int Status;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
/* 将单链表初始化为空, 动态生成一个头结点, 并将头结点的指针域置为空 */
Status LinkListInit(LinkList *L)
{
(*L) = (LinkList)malloc(sizeof(struct LNode));
if(*L == NULL)
return -1;
(*L)->next = NULL;
return 0;
}
/* 销毁线性表 */
void LinkListDestroy(LinkList *L)
{
LinkList q;
while(*L) /* 头结点也要释放掉 */
{
q = (*L)->next;
free(*L);
(*L) = q;
}
}
/* 将L重置为空表 */
void LinkListClear(LinkList L)
{
LinkList p, q;
p = L->next; /* 第一个结点*/
while(p)
{
q = p->next;
free(p);
p = q;
}
L->next = NULL;
}
/* 判断单链表是否为空 */
Status LinkListEmpty(LinkList L)
{
return (L->next == NULL);
}
/* 返回L的长度 */
int LinkListLength(LinkList L)
{
int i = 0;
LinkList p;
p = L->next; /* 指向第一个结点 */
while(p)
{
i++;
p = p->next;
}
return i;
}
/* 当第i个元素存在时,其值赋给e */
Status LinkListGetElem(LinkList L, int i, ElemType *data)
{
int j = 1;
LinkList p;
p = L->next;
while(p != NULL && j < i) /* 从第1个结点开始,滑动i-1步到达第i个结点(1<=i<= Len) */
{
p = p->next;
j++;
}
if(p == NULL || j > i)
{
return -1;
}
*data = p->data;
}
/* 返回L中第1个与e满足关系compare()的数据元素的位序 */
int LinkListLocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, Elemtype))
{
int i = 0;
LinkList p = L->next;
while(p)
{
i++;
if(compare(p->data, e))
return i;
p = p->next;
}
return 0;
}
/* 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱 */
Status LinkListPriorElem(LinkList L, ElemType cur, ElemTpye *pre)
{
LinkList p, q;
p = L->next; /* 第一个结点 */
while(p->next) /* 有至少两个或以上的结点 */
{
q = p->next; /* q是p的后继 */
if(q->data == cur)
{
*pre = p->data; /* 前驱 */
return 0;
}
p = q;
}
return -1;
}
/* 若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继 */
Status LinkListNextElem(LinkList L, ElemType cur, ElemType *next)
{
LinkList p = L->next; /* 第一个结点 */
while(p->next) /* 当前结点有后继 */
{
if(p->data == cur)
{
*next = p->next->data;
return 0;
}
p = p->next;
}
return -1;
}
/* 在带头结点的单链线性表L中第i(1<=i<=len)个位置之前插入元素e */
Status LinkListInsert(LinkList L, int i, ElemType e)
{
int j;
LinkList p, s;
p = L; /* 指向头结点*/
j = 1;
while(p && j < i) /* 滑动到第i个结点的前一个结点处 */
{
j++;
p = p->next;
}
if(p == NULL || j > i)
{
return -1;
}
s = (LinkList)malloc(sizeof(struct LNode));
if(s == NULL)
{
return -1;
}
s->data = e;
s->next = p->next;
p->next = s;
return 0;
}
/* 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值 */
Status LinkListDelete(LinkList L, int i, ElemType *e)
{
int j = 1;
LinkList p, q;
p = L; /* 指向头结点 */
while(p->next && j < i) /* */
{
p = p->next;
j++;
}
if(p->next == NULL || j > i)
{
return -1;
}
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return 0;
}
/* 依次对L的每个数据元素调用函数vi() */
void LinkListTraverse(LinkList L, void (*vi)(ElemType))
{
LinkList p = L->next;
while(p)
{
vi(p->data);
p = p->next;
}
}
/* 单链表反转/逆序 */
Status LinkListReverse(LinkList L)
{
LinkList current, prev, pnext;
current = L->next;
pnext = current->next;
current->next = NULL;
while(pnext)
{
prev = pnext->next;
pnext->next = current;
current = pnext;
pnext = prev;
}
L->next = current;
return 0;
}
/* 单链表反转/逆序的另一个方法*/
Status LinkListRevers2(LinkList L)
{
LinkList current, p;
if(L == NULL) /* 空表返回 */
{
return ;
}
current = L->next; /* 第1个元素节点处 */
while(current->next != NULL)
{
p = current->next; /* p为要被提取出来的节点 */
current->next = p->next; /* 断开要被提取出来的节点 */
p->next = L->next; /* 被提取出来的结点插入到首元结点前面 */
L->next = p; /* 被提取出来的节点成为首元结点 */
}
return ;
}
/* 倒数第n个元素 */
Status LinkListGetNthNodeFromBack(LinkList L, int n, ElemType *e)
{
int i = 0;
LinkList firstNode, secNode;
firstNode = L;
secNode = L;
while(i < n && firstNode->next != NULL)
{
/* 正数n个节点,firstNode指向正的第n个节点 */
i++;
firstNode = firstNode->next;
}
if(firstNode->next == NULL && i < n - 1)
{
/* 节点数量少于n个 */
return -1;
}
while(firstNode != NULL)
{
secNode = secNode->next;
firstNode = firstNode->next;
}
*e = secNode->data;
return 0;
}
/* 获取中间结点 */
Status LinkListGetMidNode(LinkList L, ElemType *e)
{
LinkList search, mid;
mid = search = L;
while(search->next != NULL)
{
if(search->next->next != NULL)
{
search = search->next->next;
mid = mid->next;
}
else
{
search = search->next;
}
}
*e = mid->data;
return 0;
}
/* 判断是否有环 */
int LinkListHasLoop(LinkList L)
{
LinkList p, q;
p = q = L;
while(p != NULL && q != NULL && q->next != NULL)
{
p = p->next;
if(q->next != NULL)
q = q->next->next;
if(p == q)
return 1;
}
return 0;
}
/* 判断是否有环的另外一个方法 */
int LinkListHasLoop2(LinkList L)
{
LinkList p, q;
int pos1, pos2;
p = q = L;
pos1 = 0;
while(p)
{
q = L;
pos2 = 0;
pos1++;
while(q)
{
pos2++;
if(p == q)
{
if(pos1 == pos2)
break;
else
return 1;
}
q = q->next;
}
p = p->next;
}
}
/* 单链表建环, num:环入口的节点 */
Status LinkListBulidLoop(LinkList *L, int num)
{
int i = 0;
LinkList cur = *L;
LinkList tail = NULL;
if(num <= 0 || L == NULL)
{
return -1;
}
for(i = 0; i < num; i++) /* 找到入口节点位置 */
{
if(cur == NULL)
{
return -1;
}
cur = cur->next;
}
tail = cur;
while(tail->next)
{
tail = tail->next;
}
tail->next = cur;
return 0;
}
/* 删除重复元素 */
LinkList LinkListRemoveDupNode(LinkList L)
{
LinkList p, q, r;
p = L->next; /* 第一个元素节点 */
while(p)
{
q = p;
while(q->next)
{
if(q->next->data == p->data)
{
r = q->next;
q->next = r->next;
free(r);
}
else
{
q = q->next;
}
}
p = p->next;
}
return L;
}