链表及其运用
单向链表的实现方法:
#include <stdio.h>
#include <stdlib.h>
struct list
{
int data;
struct list *next;
};
/*创建一个节点*/
struct list *create_list()
{
return calloc(sizeof(struct list) , 1);
}
/*打印链表的内容*/
void traverse(struct list *p)
{
//循环实现
//p = p->next;//头节点不需要打印
//while(p)
//{
// printf("%d\n" , p->data);
// p = p->next;
//}
//递归实现
if (p->next == NULL)
return;
printf("%d\n" , p->next->data);
traverse(p->next);
}
/*向链表插入一个节点*/
int insert_list(struct list *p , int n , int data)
{
while (p && n--)
p = p->next;
if (p == NULL)
return 0;
struct list *node = create_list();
node->data = data;
node->next = p->next;
p->next = node;
return 1;
}
/*删除链表的一个节点*/
int delete_list(struct list *p , int n)
{
while (p && n--)
p = p->next;
if (p == NULL)
return 0;
struct list *temp = p->next;
if (temp == NULL)
return 0;
p->next = temp->next;
free(temp);
return 1;
}
/*计算链表节点的数量*/
int count_list(struct list *p)
{
int count = 0;
while(p->next)//不计算头节点
{
p = p->next;
count++;
}
return count;
}
/*清空一个链表,只保留头节点*/
void clear_list(struct list *p)
{
struct list *head = p;
p = p->next;
while(p)
{
struct list * tmp = p->next;
free(p);
p = tmp;
}
head->next = NULL;
}
/*判断一个链表是否为空*/
int empty_list(struct list *p)
{
if(p->next != NULL)
return 0;
else
return 1;
}
/*返回链表指定位置的节点*/
struct list *locale_list(struct list *p , int n)
{
p = p->next;
while(p && n--)
{
p = p->next;
}
return p;
}
/*返回数据等于data的节点*/
struct list *data_list(struct list *p , int data)
{
p = p->next;
while(p)
{
if(p->data == data)
return p;
}
return NULL;
}
/*返回数据等于data的节点位置*/
int data_pos(struct list *p , int data)
{
int index = 0;
p = p->next;
while(p)
{
if(p->data == data)
break;
p = p->next;
index++;
}
return index;
}
/*返回链表中最后一个节点*/
struct list *last_list(struct list *p)
{
while(p->next)
{
p = p->next;
}
return p;
}
/*合并两个链表,结果放入第一个链表内*/
void merge_list(struct list *p , struct list *q)
{
struct list *p_last = last_list(p);
p_last->next = q->next;
free(q);
}
/*逆置一个链表*/
struct list *reverse_list(struct list *p)
{
struct list *pre = p;
struct list *cur = p->next;
struct list *next = NULL;
struct list *last = p->next;
while(cur)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
last->next = NULL;
p->next = pre;
}
int main(void)
{
struct list *head = create_list();
int i;
for (i = 0 ; i < 4 ; i++)
{
insert_list(head,i,i);
}
traverse(head);
printf("%d\n",last_list(head)->data);
return 0;
}
head -> first -> second -> null
优化后的链表程序:
#include <stdio.h>
#include <stdlib.h>
struct list
{
int data;
struct list * next;
};
//打印一个链表
void traverse_list(struct list *ls)
{
struct list * p = ls->next;//不打印头节点
while(p)
{
printf("%d\n",p->data);
p = p->next;
}
}
//创建一个节点空间
struct list *create_list()
{
return calloc(sizeof(struct list) , 1);
}
//插入一个节点
struct list *insert_list(struct list * ls , int n , int data)
{
struct list * p = ls;
while(p && n--)
{
p = p->next;
}
if(!p)
return NULL;
struct list *node = create_list();
node->next = p->next;
node->data = data;
p->next = node;
return p;
}
//删除一个节点
int delete_list(struct list *ls , int n)
{
struct list *p = ls;
while (p && n--)
{
p = p->next;
}
struct list *tmp = p->next;
p->next = tmp->next;
free(tmp);
}
//初始化一个链表
struct list *init_list(int n)
{
struct list *head = create_list();
int i;
for(i = 0 ; i < n ; i++)
insert_list(head,i,i);
return head;
}
//统计节点的数量
int count_list(struct list *ls)
{
struct list * p = ls->next;
int count = 0;
while(p)
{
p = p->next;
count++;
}
return count;
}
//清空链表
void clear_list(struct list *ls)
{
struct list * p = ls->next;
while(p)
{
struct list * tmp = p->next;
free(p);
p = tmp;
}
ls->next = NULL;
}
//判断一个链接是否为空
int empty_list(struct list *ls)
{
struct list *p = ls->next;
if (p!=NULL)
return 0;
else
return 1;
}
//返回链表指定位置的节点
struct list *locale_list(struct list *ls , int n)
{
struct list * p = ls->next;
while(p && n--)
{
p = p->next;
}
return p;
}
//返回链接等于data的节点
struct list *data_list(struct list *ls , int data)
{
struct list *p = ls->next;
while (p)
{
if (p->data == data)
break;
p = p->next;
}
return p;
}
//返回链表等于data的位置
int pos_list(struct list *ls , int data)
{
struct list *p = ls->next;
int index = 0;
while (p)
{
if(p->data == data)
break;
p = p->next;
index++;
}
return index;
}
//得到最后一个节点
struct list *last_list(struct list *ls)
{
struct list *p = ls->next;
struct list *pre = p;
while(p)
{
pre = p;
p = p->next;
}
return pre;
}
//合并两个链表,放入第一个链表中
void merge_list(struct list *ls1 , struct list *ls2)
{
struct list *last = last_list(ls1);
last->next = ls2->next;
free(ls2);
}
//链表逆置
void reverse_list(struct list *ls)
{
struct list *pre = ls;
struct list *cur = ls->next;
struct list *next = NULL;
struct list *last = ls->next;
while (cur)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
last->next = NULL;
ls->next = pre;
}
int main(void)
{
struct list *head = init_list(10);
traverse_list(head);
return 0;
}
注重理解下面左值和右值的区别
node->next = p->next;
p->next = node;
把本班的同学读入到结构体数组里,加上序号,利用链表并且冒泡排序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
struct student
{
int ID;
char name[20];
};
struct list
{
struct student st;
struct list *next;
};
struct list *create_list()
{
return calloc(1,sizeof(struct list));
}
struct list *insert_list(struct list *ls , int n, struct student s)
{
struct list *p = ls;
while (p && n--)
p = p->next;
if(!p)
return NULL;
struct list *node = create_list();
node->st = s;
node->next = p->next;
p->next = node;
return node;
}
void traverse_list(struct list *ls)
{
struct list *p = ls->next;
while(p)
{
printf("%d:%s\n",p->st.ID,p->st.name);
p = p->next;
}
}
void init_list(struct list *ls)
{
struct list *head = ls;
FILE *fp = fopen("student.bin","r");
while(!fp)
return;
struct student st;
int index = 0;
while(fread(&st,sizeof(struct student),1,fp) > 0)
{
insert_list(head,index,st);
index++;
}
}
void sort_list(struct list *ls , int n)
{
struct list *p = NULL;
struct student tmp;
int i,j,min;
for (i = 0; i < n ; i++)
{
p = ls->next;
for (j = 0; j < n-i-1; j++)
{
if (p->st.ID > p->next->st.ID)
{
tmp = p->st;
p->st = p->next->st;
p->next->st = tmp;
}
p = p->next;
}
}
}
void init_stubin()
{
srand((unsigned)time(NULL));
FILE *fp1 = fopen("student.txt","r");
FILE *fp2 = fopen("student.bin","w");
while(!fp1 || !fp2)
return;
char buf[1024];
struct student st;
memset(&st,0,sizeof(st));
int arr[42] = {0};
int pos;
while(fgets(buf,sizeof(buf),fp1) != NULL)
{
if(buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
pos = rand()%42;
while(arr[pos] == 1)
pos = rand()%42;
arr[pos] = 1;
st.ID = pos;
strcpy(st.name,buf);
fwrite(&st,sizeof(st),1,fp2);
}
fclose(fp1);
fclose(fp2);
}
int main(void)
{
init_stubin();
struct list *head = create_list();
init_list(head);
//traverse_list(head);
sort_list(head,42);
traverse_list(head);
return 0;
}