您的位置:首页 > 其它

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

2015-07-09 17:49 901 查看
对单向链表的各种操作做了总结,并且考虑到了每个操作的特殊情况,对特殊情况也要求能够正确处理。

typedef struct link
{
struct link *next;
int date;
}Link,*List;

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

List creat()
{
Link *st = init(),*p;
p = st;
int k;
while(p != NULL && scanf("%d",&k) != EOF) //默认EOF=-1,当scanf中输入ctrl+z时,返回值为-1
{
Link *temp = malloc(sizeof(*temp)); //头节点为空,
temp->date = k;
temp->next = NULL;
p->next = temp;
p = p->next;
}
return st->next;  //返回头结点的下一节点
}
//判断链表是否为空
int linkempty(List st)
{
if(st == NULL)
{
printf("The one-way link is empty!\n");
return 0;
}
else
return 1;
}
//统计链表元素个数
int linksize(List st)
{
int sum = 0;
while(st != NULL)
{
sum++;
st = st->next;
}
return sum;
}
//在顺序链表中插入元素,保持元素仍然有序
List orderinsert(List st,int k)
{
Link *head = malloc(sizeof(*head));
Link *pre,*p = head;
pre = head;
head->next = st;
for(p = p->next;p != NULL;)
{
if(p->date > k)
break;
pre = p;
p = p->next;
}
if(p == NULL)             //链表中元素都不大于k
{
Link *tmp = malloc(sizeof(*tmp));
tmp->date = k;
tmp->next = NULL;
pre->next = tmp;
}
else
{
Link *tmp = malloc(sizeof(*tmp));
tmp->date = k;
tmp->next = p;
pre->next = tmp;
}
return head->next;
}
//在无序链表中的第i个位置后插入元素k
List disorderinsert(List st,int i,int k)
{
int t = 0;
Link *p = st,*pre;
if(i == 0)                   //在头节点处插入
{
printf("Insert to the head!\n");
Link *tmp = malloc(sizeof(*tmp));
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");
Link *tmp = malloc(sizeof(*tmp));
pre->next = tmp;
tmp->date = k;
tmp->next = NULL;
}
else
{
Link *tmp = malloc(sizeof(*tmp));
pre = p->next;
p->next = tmp;
tmp->date = k;
tmp->next = pre;
}
}
return st;
}
//删除元素k
List datedelete(List st,int k)
{
Link *p, *pre = malloc(sizeof(*pre));
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)
{
Link *p = st,*pre;
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)
{
Link *p = st;
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)
{
Link *p,*mid;
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);
}
//链表的反转
List linkreverse(List st)
{
if(st->next == NULL)
{
printf("Signle node link!\n");
return st;
}
else if(st->next->next == NULL)
{
printf("Only two nodes!\n");
Link *tmp = st->next;
st->next->next = st;
st->next = NULL;
return tmp;

}
else
{
Link *pre, *p,*tmp;
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;
}
//插入排序
List linkinsertsort(List st)
{
Link *p,*head = malloc(sizeof(*head));
Link *q;
head->next = st;
p = head;
q = NULL;
for(p = p->next;p != NULL;p = p->next)
q = orderinsert(q,p->date);
return q;
}
//将两个有序链表进行归并
List combine(List st1,List st2)
{
Link *st = malloc(sizeof(*st));
Link *p,*q,*head = st;
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;
return head->next;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: