网上看了好多的单链表的代码,有些写的很好,有些写的异常判断稍微少了些,有些写的不太符合自己的想法,所以自己也来整理一下,哈哈
参加工作也有段时间了,对于带结点的单链表操作倒是没有怎么用过,毕竟都是调用的公司的库函数,
最近一段时间想回来再看看C语言基础,发现真的不怎么样,唉。下面是自己写的,可能也有不少问题,各位看官提提意见。
#include "stdio.h"
#include <MALLOC.H>
typedef struct student
{
int data;
struct student *next;
}t_link_node;
// 创建链表 带头结点
t_link_node *create_link(void)
{
t_link_node *head, *p, *end;//定义头节点,普通节点,尾部节点
int input, cycle=1;
head = (t_link_node*)malloc(sizeof(t_link_node));//分配地址
if (NULL == head) return NULL;
end = head;
while(cycle)
{
printf("input data:(end with 0) ");
scanf("%d", &input);
if (0 != input)
{
p = (t_link_node *)malloc(sizeof(t_link_node));
if (NULL == head)
{
break;
}
p->data = input;
end->next = p;
end = p;
}
else
{
cycle = 0;
}
}
end->next = NULL;//结束创建
return head;
}
//.清除线性表中的所有元素,即释放所有节点(除了头结点),使之成为一个空表
void list_destroy(t_link_node *head)
{
t_link_node *p, *p_next;
if (NULL == head)
{
return;
}
p = head->next;
while (p != NULL)
{
p_next = p->next;
free(p);
p =p_next;
}
head->next = NULL;
printf("清空链表,保留头结点\n");
}
//链表的长度
int link_length(t_link_node *head)
{
int len=0;
t_link_node *p;
if (NULL == head)
{
return 0;
}
p = head->next;
while (p)
{
p=p->next;
len++;
}
return (len);
}
//打印链表节点
void link_print(t_link_node *head)
{
int index=0;
t_link_node *p;
if (NULL == head)
{
return 0;
}
printf("\n");
if (0 == link_length(head))
{
printf("Link Info : Null\n");
}
p = head->next;
while (p)
{
printf("Link Info[ID=%d]data=%d\n", index, p->data);
p=p->next;
index++;
}
}
// 删除一个节点
int link_del(t_link_node *head,int num)//删除一个节点
{
t_link_node *p_list_del;
t_link_node *p2;
printf("\n*******link_del ***********\n");
if (NULL == head || NULL == head->next)
{
printf("link_del is NULL\n");
return 0;
}
p_list_del = head->next;
p2 = head;
while(p_list_del != NULL && p_list_del->data != num)
{
p2 = p_list_del;
p_list_del = p_list_del->next;
}
if(NULL == p_list_del)
{
printf("didn't find the data\n");
return 0;
}
p2->next = p_list_del->next;
free(p_list_del);
return 1;
}
// 链表的选择排序法
int link_sort(t_link_node *head)
{
t_link_node *p1;
t_link_node *p2,*p_smaller;
if (NULL == head || NULL == head->next)
{
printf("link_sort is NULL\n");
return 0;
}
printf("\n*******link_sort ***********\n");
//simple select sort
//for (i=0;i<n-1;i++)
for (p1=head->next; p1->next;p1=p1->next)
{
//smaller = i;
p_smaller = p1;
//for (j=i+1;j<n;j++)
for (p2=p1->next;p2;p2=p2->next)
{
if (p2->data < p_smaller->data)
{
//smaller = j;
p_smaller = p2;
}
}
//if (smaller != i)
if (p1 != p_smaller)
{
//异或 用来互换元素
p1->data ^= p_smaller->data;
p_smaller->data ^= p1->data;
p1->data ^= p_smaller->data;
}
}
return 1;
}
// 链表的向头部插入一个节点
int link_insert_head(t_link_node *head, int num)
{
t_link_node *p1;
t_link_node *p2,*p_new;
if (NULL == head)
{
printf("link_insertHead is NULL\n");
return 0;
}
printf("\n*******link_insertHead ***********\n");
if (p_new = (t_link_node *)malloc(sizeof(t_link_node)))
{
p_new->data = num;
p_new->next = head->next; // 不管head->next一开始就是NULL,还是非NULL,都是这么表示
head->next = p_new;
}
return 1;
}
// 链表的向尾部插入一个节点
int link_insert_tail(t_link_node *head, int num)
{
t_link_node *p1;
t_link_node *p2,*p_new;
if (NULL == head)
{
printf("link_insertTail is NULL\n");
return 0;
}
printf("\n*******link_insertTail ***********\n");
p1 = head;
//一直到结尾为止,这样写法可以少一个中间变量
//不然要写成
//p1 = head->next;
//while (p1)
//{
// p_last = p1;
// p1 = p1->next;
//}
//后面就用p_last来表示最后一个节点
//
//而目前做法是p1=head,然后再p1->next就可以用p1来表示最后一个节点
//
while (p1->next != NULL)
{
p1 = p1->next;
}
if (p_new = (t_link_node *)malloc(sizeof(t_link_node)))
{
p_new->data = num;
p_new->next = NULL;//既然是尾节点了,就直接等于NULL
p1->next = p_new;
}
return 1;
}
// 链表的按照顺序进行插入结点
int link_insert_sequence(t_link_node *head, int num)
{
t_link_node *p1;
t_link_node *p2,*p_new;
if (NULL == head)
{
printf("link_insertsequence is NULL\n");
return 0;
}
printf("\n*******link_insertsequence ***********\n");
p1 = head->next;
p2 = head;
while (p1 != NULL && p1->data < num)
{
p2 = p1;
p1 = p1->next;
}
if (p_new = (t_link_node *)malloc(sizeof(t_link_node)))
{
p_new->data = num;
p_new->next = p1;//p1可能找了半天没有找到节点而导致的NULL,也可能是中间的一个节点,也可能是head->next就是NULL
p2->next = p_new;
}
return 1;
}
// 链表的逆置
void link_reverse(t_link_node *head)
{
t_link_node *p,*q;
if (NULL == head || NULL == head->next)
{
return;
}
p= head->next;
head->next = NULL;
printf("\n*******Start Link_Reverse...****\n");
while (p)
{
q = p;
p = p->next;
q->next = head->next;
head->next = q;
}
}
// 测试函数
void main(void)
{
int len;
t_link_node *head;
head = create_link();
len = link_length(head);
printf("Len=%d\n", len);
link_print(head);
link_reverse(head);
link_print(head);
link_del(head, 1);
link_print(head);
link_sort(head);
link_print(head);
link_insert_head(head,99);
link_print(head);
link_insert_tail(head,102);
link_print(head);
//list_destroy(head);
link_insert_tail(head,7001);
link_print(head);
link_insert_sequence(head, 7002);
link_print(head);
}