# 单向链表的相关操作总结：创建、删除、查找、排序、统计链表大小、链表的反转和遍历等

typedef struct link
{
int date;

//链表的创建
List init()
{
if(st == NULL )
{
printf("Memory Erroy!\n");
return NULL;
}
else
st->next = NULL;
return st;
}

List creat()
{
p = st;
int k;
while(p != NULL && scanf("%d",&k) != EOF) //默认EOF=-1，当scanf中输入ctrl+z时，返回值为-1
{
temp->date = k;
temp->next = NULL;
p->next = temp;
p = p->next;
}
return st->next;  //返回头结点的下一节点
}
//判断链表是否为空
{
if(st == NULL)
{
return 0;
}
else
return 1;
}
//统计链表元素个数
{
int sum = 0;
while(st != NULL)
{
sum++;
st = st->next;
}
return sum;
}
//在顺序链表中插入元素，保持元素仍然有序
List orderinsert(List st,int k)
{
for(p = p->next;p != NULL;)
{
if(p->date > k)
break;
pre = p;
p = p->next;
}
if(p == NULL)             //链表中元素都不大于k
{
tmp->date = k;
tmp->next = NULL;
pre->next = tmp;
}
else
{
tmp->date = k;
tmp->next = p;
pre->next = tmp;
}
}
//在无序链表中的第i个位置后插入元素k
List disorderinsert(List st,int i,int k)
{
int t = 0;
if(i == 0)                   //在头节点处插入
{
tmp->date = k;
tmp->next = p;
st = tmp;
}
else
{
while(p != NULL && t < i)
{
t++;
pre = p;
p = p->next;
}
if(t <= i)
{
printf("Insert the new node to the tail!\n");
pre->next = tmp;
tmp->date = k;
tmp->next = NULL;
}
else
{
pre = p->next;
p->next = tmp;
tmp->date = k;
tmp->next = pre;
}
}
return st;
}
//删除元素k
List datedelete(List st,int k)
{
int t = 0;
p = st;
if(p->next == NULL)  //链表为单节点链表
{
if(p->date == k)
printf("Signle node link and %d is root.\n",k);
else
printf("Signle node link and NO %d !\n",k);
return NULL;
}
else
{
pre->next = st;
st = pre;
while(pre->next != NULL)
{
p = pre->next;
if(p->date == k)
{
pre->next = p->next;
free(p);
t++;
}
else
pre = p;
}
if(!t)
printf(" NO %d!\n",k);
return st->next;
}
}
//在顺序链表中删除第i个最小元素
List locatedelete(List st,int i)
{
int k,t = 1;
k = p->date;
pre = p->next;
if(i == 1)  //删除最小元素（从头节点开始删除）
{
free(p);
p = pre;
while(p != NULL && p->date == k) //考虑有多个相同元素（算一个等级，如：第一个最小）的情况
{
pre = p->next;
free(p);
p = pre;
}
if(p == NULL)
{
printf("NULL!\n");
return NULL;
}
else
return p;
}
else     //删除第i个最小元素（i!=1,且第i个最小元素可能有多个）
{
p = p->next;
while(p != NULL)
{
if(p->date != k)
{
t++;
k = p->date;
}
if(t == i)
break;
else
{
pre = p;
p = p->next;
}
}
if(t < i)
printf("The %dth min-date is NOT exist!\n",i);
else
{
if(t == i)
{
pre->next = p->next;
p = p->next;
while(p != NULL && k == p->date)
{
pre->next = p->next;
p = p->next;
}
}
}
return st;
}
}
//查询元素k是否在链表中（0：链表中无此元素；否则元素存在）
int datesearch(List st,int k)
{
int i = 0;
while(p != NULL)
{
if(p->date == k)
i++;
p = p->next;
}
return i;
}
//已知链表大小时寻找链表的中间元素
int middledateN(List st,int N)
{
int i = 1;
if(N%2 == 0)
{
while(i != N/2)
{
i++;
st = st->next;
}
return st->date;
}
else
{
while(i != N/2)
{
i++;
st = st->next;
}
return st->next->date;
}
}
//链表大小未知时，寻找中间元素
int middledate(List st)
{
p = st;
mid = st;   //设置两个指针，mid为中间指针
while(p->next != NULL)
{
p = p->next;
if(p->next != NULL)
{
p = p->next;
mid = mid->next;
}
}
return (mid->date);
}
//链表的反转
{
if(st->next == NULL)
{
return st;
}
else if(st->next->next == NULL)
{
printf("Only two nodes!\n");
st->next->next = st;
st->next = NULL;
return tmp;

}
else
{
pre = NULL;
p = st;
while(p->next != NULL)
{
tmp = p->next;
p->next = pre;
pre = p;
p = tmp;
}
p->next = pre;
return p;
}
}
//链表的遍历
void traverse(List st)
{

while(st != NULL)
{
printf("%3d",st->date);
st = st->next;
}
printf("\n");
return;
}
//插入排序
{
q = NULL;
for(p = p->next;p != NULL;p = p->next)
q = orderinsert(q,p->date);
return q;
}
//将两个有序链表进行归并
List combine(List st1,List st2)
{
p = st1;
q = st2;
while(p != NULL && p != NULL)
{
if(p->date < q->date)
{
st->next = p;
st = p;
p = p->next;
}
else
{
st->next = q;
st = q;
q = q->next;
}
}
st->next = (p == NULL) ? q : p;
}