1、尾插法寄创建一个链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//尾插法创建链表;
struct node *create_list_by_tail()
{
struct node *head = NULL; //头指针
struct node *pnew = NULL; //申请新的节点
struct node *tail = NULL; //保存最后一个节点的地址
int x;
scanf("%d", &x);
while(getchar()!='\n');
while(x)
{
//1、创建新的节点
pnew = (struct node*)malloc(sizeof(struct node));
if(NULL == pnew)
{
printf("malloc error, %s,%d\n", __FILE__, __LINE__);
exit(-1);
}
pnew->data = x;
pnew->next = NULL;
//2、加入链表
if(head == NULL)
{
head = pnew;
tail = pnew;
}
else
{
tail->next = pnew;
tail = pnew;
}
scanf("%d", &x);
while(getchar()!='\n');
}
return head;
}
2、头插法创建一个链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//头插法创建链表;
struct node *create_list_by_head()
{
struct node *head = NULL, *pnew = NULL;
int x;
scanf("%d", &x);
while(getchar()!='\n');
while(x)
{
//1、创建新的节点,并赋值
pnew = (struct node*)malloc(sizeof(struct node));
if(NULL == pnew)
{
printf("malloc error, %s, %d\n", __FILE__,__LINE__);
exit(-1);
}
pnew->data = x;
pnew->next = NULL;
//2、加入链表
#if 0
if(NULL == head)
{
head = pnew;
}
else
{
pnew->next = head;
head = pnew;
}
#endif
pnew->next = head;
head = pnew;
scanf("%d", &x);
while(getchar()!='\n');
}
return head;
}
3、创建一个新的节点
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
struct node* create_node()
{
struct node *pnew = NULL;
pnew = (struct node*)malloc(sizeof(struct node));
if(NULL == pnew)
{
printf("malloc error, %s, %d\n", __FILE__, __LINE__);
exit(-1);
}
pnew->next = NULL;
return pnew;
}
4、计算链表的长度
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//计算链表长度;
int list_len(struct node *head)
{
int count = 0;
while(head != NULL)
{
count ++;
head = head->next;
}
return count;
}
5、查找节点
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//根据节点序号查找操作
/*
*函数原型: struct node* list_search_by_index(struct node *head, int index)
*功能说明:根据节点序号查找操作
*参数说明:head: 链表的头指针 index:查找节点的序号
*返回值说明: 成功返回对应节点地址,失败返回NULL
*其他: 节点序号从1开始
*/
struct node* list_search_by_index(struct node *head, int index)
{
//入参检查
if(NULL == head)
{
return NULL;
}
int len = list_len(head);
if(index < 1 || index>len)
{
printf("param error!%s, %d\n", __FILE__,__LINE__ );
return NULL;
}
//正确流程
struct node *p = head;
for(int i=1; i<index; i++ )
{
p = p->next;
}
return p;
}
5、插入节点
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//根据节点序号插入一个新的节点;
//中间或者尾部插入返回原来的head
//头插返回改变后的头指针
struct node *list_insert_by_index(struct node *head, int index, int data)
{
//入参检查
int len = list_len(head);
#if 0
int len = list_len(head);
if(index<1 || index>len+1)
{
printf("param error!%s, %d\n", __FILE__,__LINE__);
return head;
}
#endif
if(index<1)
{
index = 1;
}
if(index>len+1)
{
index = len+1;
}
//正确流程
struct node * pnew=NULL;
pnew = create_node();
pnew->data = data;
if(1 == index)// 头插
{
pnew->next = head;
head = pnew;
}
else //中间或者尾部插入
{
struct node *psearch = NULL;
psearch = list_search_by_index(head, index-1);
pnew->next = psearch->next;
psearch->next = pnew;
}
return head;
}
6、删除节点
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//根据节点序号删除节点;
struct node*list_del_by_index(struct node *head, int index)
{
//入参检查
if(NULL == head)
{
return head;
}
int len = list_len(head);
if(index<1 || index>len)
{
return head;
}
//正确流程:(1)保存删除节点地址(2)将删除节点从链表上移下来 (3)释放空间
struct node *pdel = NULL ; //保存删除节点的地址
if(1 == index) //头删
{
pdel = head;
head = head->next;
}
else //中间删除 或者尾部删除
{
struct node *psearch = NULL;
psearch = list_search_by_index(head, index-1);
pdel = psearch->next;
psearch->next = pdel->next;
}
free(pdel);
return head;
}
7、释放内存
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//释放链表内存(二级指针)
void list_free(struct node* *phead)
{
struct node *pdel = NULL;
while(*phead != NULL)
{
pdel = *phead;
*phead = (*phead)->next;
free(pdel);
}
}
//释放链表内存(一级指针)
struct node* list_free1(struct node *head)
{
struct node *pdel = NULL;
while(head != NULL)
{
pdel = head;
head = head->next;
free(pdel);
}
return head;
}
8、反序链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//反序输出链表;
struct node*list_rev(struct node *head)
{
struct node *new_head = NULL;
struct node *p = NULL;
while(head != NULL)
{
p = head;
head = head->next;
p->next = new_head;
new_head = p;
}
return new_head;
}
9、链表的升序排列
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//链表升序排序
//1、从旧链表中找到最大值
struct node* find_max_from_oldlist(struct node*head)
{
struct node *pmax = head;
struct node *p = head;
while(p != NULL)
{
if(p->data > pmax->data)
{
pmax = p;
}
p = p->next;
}
return pmax;
}
//2、将最大值从旧链表中移除
struct node* move_max_from_oldlist(struct node* head, struct node *pmax)
{
if(head == pmax)//头部移除
{
head = head->next;
}
else
{
struct node *p = head;
while(p->next != pmax) //找最大值前面的一个节点
{
p = p->next;
}
p->next = pmax->next;
}
pmax->next = NULL;
return head;
}
//3、将最大值加入新的链表
struct node* add_newlist(struct node* new_head, struct node* pmax)
{
pmax->next = new_head;
new_head = pmax;
return new_head;
}
struct node *list_sort(struct node *head)
{
struct node *new_head = NULL;
struct node *pmax = NULL;
while(head != NULL)
{
//1、从旧链表中找到最大值
pmax = find_max_from_oldlist(head);
//2、将最大值从旧链表中移除
head = move_max_from_oldlist(head, pmax);
//3、将最大值加入新的链表
new_head = add_newlist(new_head, pmax);
}
return new_head;
}
10、显示链表数据
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
void show_list(struct node *head)
{
if(NULL == head)
{
printf("list empty!\n");
return ;
}
struct node *p = head;
while(p!=NULL)
{
printf("[%d|%p]-->", p->data, p->next);
p = p->next;
}
printf("\n");
}
11、链表数据的读写操作
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
//写链表数据进.txt文件
//成功:0
//失败:-1
int write_list(struct node *head)
{
//打开文件
FILE *fp = NULL;
fp = fopen("./data.txt", "wb");
if(NULL == fp)
{
perror("fopen");
return -1;
}
//写文件
struct node *p = head;
int ret;
while(p!=NULL)
{
ret = fwrite(p, sizeof(struct node), 1, fp);
if(ret<1)
{
perror("fwrite");
fclose(fp);
return -1;
}
p = p->next;
}
//关闭文件
fclose(fp);
return 0;
}
//从.txt中读取文件;
struct node* read_list()
{
struct node *head = NULL, *pnew = NULL;
//打开文件
FILE *fp = NULL;
fp = fopen("./data.txt", "rb");
if(NULL == fp)
{
perror("fopen");
return head;
}
//读文件
int ret;
while(1)
{
pnew = create_node();
ret = fread(pnew, sizeof(struct node), 1, fp);
if(0 == ret) //到达文件结尾
{
break;
}
pnew->next = head;
head = pnew;
}
free(pnew);
//关闭文件
fclose(fp);
return head;
}
12、测试主函数
1、创建节点→创建链表→计算长度→显示链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = create_list_by_tail();
//head = create_list_by_head();
int len = list_len(head);
printf("表长为:%d\n", len);
show_list(head);
return 0;
}
2、创建节点→创建链表→计算长度→显示链表→根据节点号查找
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = create_list_by_tail();
//head = create_list_by_head();
int len = list_len(head);
printf("表长为:%d\n", len);
show_list(head);
int index;
printf("请输入查找节点序号:");
scanf("%d", &index);
struct node *psearch = list_search_by_index(head, index);
if(NULL == psearch)
{
printf("节点不存在!\n");
}
else
{
printf("psearch : %p\n", psearch);
}
return 0;
}
3、创建节点→创建链表→计算长度→显示链表→根据节点号查找→添加节点→显示添加后的链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = create_list_by_tail();
//head = create_list_by_head();
int len = list_len(head);
printf("表长为:%d\n", len);
show_list(head);
int index;
printf("请输入查找节点序号:");
scanf("%d", &index);
struct node *psearch = list_search_by_index(head, index);
if(NULL == psearch)
{
printf("节点不存在!\n");
}
else
{
printf("psearch : %p\n", psearch);
}
printf("请输入插入的位置:");
scanf("%d", &index);
head = list_insert_by_index(head, index, 666);
show_list(head);
return 0;
}
4、创建节点→创建链表→计算长度→显示链表→根据节点号查找→删除节点→显示删除后的链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = create_list_by_tail();
//head = create_list_by_head();
int len = list_len(head);
printf("表长为:%d\n", len);
show_list(head);
int index;
printf("请输入查找节点序号:");
scanf("%d", &index);
struct node *psearch = list_search_by_index(head, index);
if(NULL == psearch)
{
printf("节点不存在!\n");
}
else
{
printf("psearch : %p\n", psearch);
}
printf("请输入删除节点序号:");
scanf("%d", &index);
head = list_del_by_index(head, index);
show_list(head);
return 0;
}
5、创建节点→创建链表→计算长度→显示链表→反转链表→显示链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = create_list_by_tail();
//head = create_list_by_head();
int len = list_len(head);
printf("表长为:%d\n", len);
show_list(head);
head=list_rev(head);
show_list(head);
return 0;
}
6、创建节点→创建链表→计算长度→显示链表→链表升序排序→显示链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = create_list_by_tail();
//head = create_list_by_head();
int len = list_len(head);
printf("表长为:%d\n", len);
show_list(head);
head=list_sort(head);
show_list(head);
return 0;
}
7、创建节点→创建链表→计算长度→显示链表→写文件
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = create_list_by_tail();
//head = create_list_by_head();
int len = list_len(head);
printf("表长为:%d\n", len);
show_list(head);
write_list(head);
return 0;
}
8、读文件→显示链表
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main()
{
struct node * head = NULL;
head = read_list();
show_list(head);
return 0;
}