基本操作的注释都在代码中了,我新建的链表是用的头插法,来保证输入的顺序和检索的顺序相同
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LNode, *LinkList;
//带头结点的尾插法建立链表,链表长度为n
LinkList List_TailInsert(LinkList &L, int n)
{
L = (LinkList)malloc(sizeof(LNode));
LNode *s, *r = L;
srand(time(0));
for (int i = 0; i < n; i++)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = rand() % 100 + 1;
r->next = s;
r = s;
}
r->next = NULL;
return L;
}
//首先完成找到第i个位置的结点算法
LinkList GetNode(LinkList &L, int i)
{
if (i == 0)
{
return L;
}
int j = 0;
LNode *p = L->next;
while (p != NULL && j < i)
{
p = p->next;
j++;
}
return p;
}
//结点的插入操作需要找到其前驱元素,例如如果要在i位置插入一个结点,那么就应该找到i-1位置并插入这个新的结点
void InsertNode(LinkList &L, int i, ElemType e)
{
LNode *s, *p = GetNode(L, i - 1);
s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
} //学习了头插法之后,插入操作不在话下
// 扩展:如果规定了就要在特定的p结点之前插入一个结点(p结点之前透明),那么可以采用交换元素操作
//,可以采取在p结点后新插入一个结点,然后交换p结点与新建结点中的元素,我觉得这个办法相当的骚
void Head_InsertNode(LinkList &L, int i, ElemType e)
{
LNode *s, *p = GetNode(L, i); //这里为了方便就选取第i个位置进行示范,以区别于InsertNose函数
s->next = p->next;
p->next = s;
//交换元素
s->data = p->data;
p->data = e;
}
//删除一个结点
void DeleteNode(LinkList &L, int i)
{
//找到位置为i-1的p结点
LNode *q, *p = GetNode(L, i - 1);
q = p->next;
p->next = q->next;
free(q);
}
/*void DeleteNode(LinkList &L, int i)
{
//找到位置为i-1的p结点
LNode *p = GetNode(L,i-1);
p->next = q->next->next;
free(p);
这样就把p结点给释放了,总之要保存要删除的结点,因为后续要调用free()函数
}*/
//求链表长度
int GetLength(LinkList &L)
{
int count = 0;
LNode *p = L->next;
while (p != NULL)
{
count++;
p = p->next;
}
return count;
}
//遍历输出整个链表的内容
void PutAllElem(LinkList &L)
{
LNode *p;
p = L->next;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
//代码调试部分
int main()
{
LinkList L;
List_TailInsert(L, 5);
PutAllElem(L);
printf("\n");
InsertNode(L, 1, 666);
PutAllElem(L);
printf("\n");
DeleteNode(L, 1);
PutAllElem(L);
printf("\n");
printf("链表的长度为:%d", GetLength(L));
printf("\n");
system("pause");
return 0;
}