还需改进:
creat_node这个函数应有返回类型,来判断新建结点是否成功,不然主函数中不管成不成功都会访问该节点成员。
改了这个函数,在主函数中create_node后要判断是否成功,不成功就提示并退出函数,退出前别忘了还要释放链表!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct node
{
int num;
struct node * next;
};
typedef struct node Node;
typedef struct node * Link;
void create_link(Link *head) //创建新链表
{
*head = NULL;
}
void insert_node_head(Link *head,Link new_node) //前插
{
new_node->next = *head;
*head = new_node;
}
void display(Link head) //按序显示链表
{
Link p = head;
if(p == NULL)
{
printf("Link is empty!\n");
return;
}
while(p != NULL)
{
printf("num = %d\n",p->num);
p = p->next;
}
}
void insert_node_tail(Link *head,Link new_node) //尾插
{
Link p;
p = *head;
if(p == NULL)
{
*head = new_node;
new_node->next = NULL;
}
else
{
while(p->next != NULL)
{
p = p->next;
}
p->next = new_node;
new_node->next = NULL;
}
}
void create_node(Link *new_node) //创建新的节点 给new_node指针分配空间
{
int count;
count = 10; //count保证如果一直申请不了空间的话,他不会一直进入死循环
do
{
*new_node = (Link)malloc(sizeof(Node));
count--;
}while(!is_malloc_ok(*new_node) && count);
}
int is_malloc_ok(Link new_node) //判断给节点分配空间是否有效
{
if(NULL == new_node)
{
printf("error malloc!\n");
return 0;
}
return 1;
}
void insert_node_mid_before(Link *head,Link new_node,int loc) //在给点节点的前面插入
{
Link p, q;
p = q = *head;
if(p == NULL)
{
printf("Link is empty!\n");
free(new_node);
return;
}
while(p->num != loc && p->next != NULL)
{
q = p;
p = p->next;
}
if(p->next == NULL)
{
if(p->num == loc)
{
new_node->next = p;
q->next = new_node;
}
else
{
printf("The node cannot be found!\n");
free(new_node);
return;
}
}
else
{
if(p == *head)
{
new_node->next = *head;
*head = new_node;
}
else
{
new_node->next = p;
q->next = new_node;
}
}
}
void insert_node_mid_after(Link head,Link new_node,int loc) //在给定节点的后面插入
{
Link p;
p = head;
if(p == NULL)
{
printf("Link is empty!\n");
free(new_node);
return;
}
while(p->num != loc && p->next != NULL)
{
p = p->next;
}
if(p->next == NULL && p->num != loc)
{
printf("The node cannot be found!\n");
free(new_node);
return;
}
else
{
new_node->next = p->next;
p->next = new_node;
}
}
delete_node(Link *head,int number) //删除节点(输入number查找到指定节点)
{
Link p, q;
p = q = *head;
if(p == NULL)
{
printf("Link is empty!\n");
}
else
{
while(p != NULL && p->num != number) //这两个条件不能颠倒!&&是短路运算符,如果颠倒,当p=NULL时判断p的num就会段错误
{
q = p;
p = p->next;
}
if(p == NULL)
{
printf("No such node!\n");
}
else
{
if(p == *head)
{
*head = (*head)->next;
free(p);
}
else
{
q->next = p->next;
}
}
}
}
int length(Link head) //返回链表的节点个数
{
Link p;
int count = 0;
p = head;
while(p != NULL)
{
count++;
p = p->next;
}
return count;
}
void release_link(Link * head) //删除并释放链表
{
Link p;
p = *head;
if(p == NULL)
{
printf("Link is empty!\n");
}
else
{
while(*head != NULL)
{
*head = (*head)->next;
free(p);
p = *head;
}
}
}
void insert_node_sort(Link *head,Link new_node) //插入后对链表里所有的数排序
{
Link p, q, k, temp;
int i, j, count;
new_node->next = *head;
(*head) = new_node;
if(new_node->next == NULL)
{
return;
}
count = length(*head);
for(i = 0; i < count - 1; i++)
{
k = *head;
q = *head;
p = (*head)->next;
for(j = 0; j < count - 1 - i; j++)
{
if(q->num > p->num)
{
q->next = p->next;
p->next = q;
if(q == *head) //不能靠判断k是否指向head
{
*head = p;
k = *head; //注意这边要让k重指向,画图看看
}
else
{
k->next = p;
}
temp = p;
p = q;
q = temp;
}
if(q == *head) //不能靠判断k是否指向head
{
q = p;
p = p->next;
}
else
{
k = q;
q = p;
p = p->next;
}
}
}
}
void insert_node_sort2(Link *head,Link new_node) //插入前链表中的数字是有序的,这次插入的数找正确的地方插入
{
Link p;
p = *head;
if(*head == NULL)
{
printf("Link is empty!\n");
}
else
{
if(new_node->num < p->num)
{
new_node->next = *head;
*head = new_node;
}
else
{
while(p->next != NULL && p->next->num < new_node->num)
{
p = p->next;
}
new_node->next = p->next;
p->next = new_node;
}
}
}
int main()
{
Link head;
Link new_node;
int i;
int location;
int num;
srand((unsigned)time(NULL));
create_link(&head);
for(i = 0; i < 10; i++)
{
create_node(&new_node);
//new_node = (Link)malloc(sizeof(Node));
new_node->num = rand() % 100;
//insert_node_head(&head,new_node);
insert_node_tail(&head,new_node); //只要指针所指向的内容,一级指针。要改变指针所指向的方向,二级指针
}
display(head);
printf("The length is %d\n\n",length(head));
/
create_node(&new_node);
printf("Please input the new node number:\n");
scanf("%d",&new_node->num);
printf("Please input the node you want to insert after:\n");
// printf("Please input the node you want to insert before:\n");
scanf("%d",&location);
// insert_node_mid_before(&head,new_node,location);
insert_node_mid_after(head,new_node,location);
display(head);
printf("The length is %d\n\n",length(head));
create_node(&new_node);
printf("Please input the node you want to insert:\n");
scanf("%d",&new_node->num);
insert_node_sort(&head,new_node);
display(head);
printf("The length is %d\n\n",length(head));
/
create_node(&new_node);
printf("Please input the node you want to insert:\n");
scanf("%d",&new_node->num);
insert_node_sort2(&head,new_node);
display(head);
printf("The length is %d\n\n",length(head));
/
printf("Please input a node number you want to delete:\n");
scanf("%d",&num);
delete_node(&head,num);
display(head);
printf("The length is %d\n\n",length(head));
release_link(&head);
display(head);
return 0;
}
每次都需要考虑一下头结点这个特殊的位置,不然容易漏。
先插入后排序的函数最好画图看一下各指针的指向(不要想当然),不然也容易错。