/*
* 内容: 链表的操作:查找,插入,删除,头插法,尾插法
* 注意:
* LinkList p, L
* p = L // p指向头结点
* p = L->next // p指向第一个结点
* 作者: wolves_liu
* 日期: 2018.3.21
* 参考: 《大话数据结构》
*/
typedef struct Node
{
int data;
struct Node *p;
}Node;
typedef struct Node *LinkList;
// 查找第i个结点,将链表L中的第i个结点的数据存入e
int List_Get(LinkList L, int i, int *e)
{
//遍历链表
int j = 1;
LinkList p;
p = L->next; // p指向第1个结点
while(p && j<i) // j=1,j<i,循环i-1次
{
p = p->next;
++j;
} // while出来之后,p是第i个结点(1+i-1);若p指向表头,循环i-1次,while出来后p是第i-1个结点(0+i-1)
if(!p || j>i)
{
return -1;
}
*e = p->data;
return 1;
}
// 插入结点
// 在链表L的第i个结点之前,插入结点s, s的数据域是e;
int List_Insert(LinkList *L, int i, int e)
{
//遍历链表
LinkList p, s;
int j = 1;
p = *L; //p指向表头结点,注意不是第一个结点
while(p && j<i)
{
p = p->next;
++j;
}
if(!p || j>i) //if(p == NULL || j>i)
{
return -1;
}
// 插入结点s
s = (LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
return 1;
}
// 删除结点
// 删除链表L的第i个结点,将该结点的数据保存到e;
int List_Insert(LinkList *L, int i, int *e)
{
LinkList p, q;
int j = 1;
p = *L; //p指向表头节点
while(p && j < i)
{
p = p->next;
++j;
}
if(!p || j>i)
{
return -1;
}
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return 1;
}
// 创建链表 —— 头插法,产生n个元素的带头结点的链表L
void Create_List_Head(LinkList *L, int n)
{
LinkList p;
int i = 0; // 计数器
srand(time(0)); // 初始化随机种子
*L = (LinkList)malloc(sizeof(Node)); // 生成一个结点,头结点是*L ;初始化链表L
*L ->next = NULL; // 头结点是指针域为空
for(i=0; i<n; i++)
{
p = (LinkList)malloc(sizeof(Node)); // 生成新结点p,第一个结点
p->data = rand()%100 + 1; // 随机生成100以内的数字
p->next = (*L)->next; // p指向第一个结点,(*L)->next是第一个结点
(*L)->next = p; // (*L)->next是头结点指向p
}
}
// 创建链表 —— 尾插法,产生n个元素的带头结点的链表L
void Create_List_Tail(LinkList *L, int n)
{
LinkList p, r;
int i = 0; // 计数器
srand(time(0)); // 初始化随机种子
*L = (LinkList)malloc(sizeof(Node)); // 生成一个结点,头结点是*L
r = *L; // r是指向尾部的结点
for(i=0; i<n; i++)
{
p = (LinkList)malloc(sizeof(Node)); // 生成新结点p
p->date = rand()%100 + 1;
r->next = p;
r = p;
}
r->next = NULL;
}
// 删除链表,L已经存在
int Delete_List(LinkList *L)
{
LinkList p, q;
p = *L->next;
while(p)
{
q = p->next; // 将p的下一个结点改名为q
free(p); // 释放p
p = q; // 将结点q当成结点p,第二次循环就会再释放p(即第二个结点)
}
*L->next = NULL; // 最后再将头结点的指针域为空
return 1;
}