线性表的链式存储
单向链表
链表结点的数据类型
typedef int DataType;
typedet struct node
{
//保存结点数据
DataType data;
//保存下一个结点的首地址
struct node *next;
}LinkNode;
常用操作
1.创建空链表,只有头结点,且其指针域为NULL
LinkNode *create_empty_linklist()
{
1.为头结点在堆区分配空间,用指针变量head保存申请空间的首地址
2.head->next = NULL;
3.head 返回
}
2.头插法,在头结点后插入新结点
int insert_head_linklist(LinkNode *head,DataType data)
{
1.为新结点在堆区分配空间,用temp保存申请空间的首地址
2.temp->data = data;
temp->next = head->next;
head->next = temp;
return 0;
}
3.尾插法,在尾结点后插入新结点
int insert_tail_linklist(LinkNode *head,DataType data)
{
1.为新结点在堆区分配空间,用temp保存申请空间的首地址
2.temp->data = data;
3.找到尾结点,
p = head;
while(p->next)
{
p = p->next;
}
4,尾结点后插入
temp->next = p->next;
p->next = temp;
return 0;
}
4.有序插入,找到插入位置前一结点
int insert_order_linklist(LinkNode *head,DataType data)
{
LinkNode *p = head;
#if 0
while(p->next)
{
if(p->next->data > data)
{
break;
}
p = p->next;
}
#endif
while(p->next && p->next->data < data)
{
p = p->next;
}
}
5.输出链表所有结点的数据
int print_linklist(LinkNode *head)
{
头结点未保存有效数据,
所有结点都遍历到
}
6.删除指定元素
int delete_assign_node(LinkNode *head,DataType data)
{
1.找到删除结点的前一结点
2.保存删除结点的首地址
3.让链表重新连接
4.释放删除结点的空间
}
7.清空整个链表
int cleanup_linklist(LinkNode *head)
{
遍历整个链表,每次删除头结点
}
code-1:head.h
#ifndef __HEAD__H
#define __HEAD__H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int DataType;
typedef struct node
{
DataType data;//保存结点数据
struct node *next;//保存下一个结点的首地址
}LinkNode;
extern LinkNode *create_empty_linklist();
extern int insert_tail_linklist(LinkNode *head,DataType data);
extern int print_linklist(LinkNode *head);
extern int insert_head_linklist(LinkNode *head,DataType data);
extern int insert_order_linklist(LinkNode *head,DataType data);
extern int inverted_linklist(LinkNode *head);
extern int order_linklist(LinkNode *head);
extern int delete_linknode(LinkNode *head,int pos);
extern int is_empty_list(LinkNode *head);
extern int delete_linklist(LinkNode *head);
extern int delete_num_node(LinkNode *head,int data);
extern int delete_num_node_byhand(LinkNode *head);
#endif
code-2:Mylinklist.c
#include "head.h"
//创建一个新的空链表
LinkNode *create_empty_linklist()/*{{{*/
{
LinkNode *head = NULL;//局部变量,放在栈中,用完及时释放空间归还内存
head = (LinkNode *)malloc(sizeof(LinkNode));//在堆区分配内存
head->next = NULL;//堆区分配对空链表,规定头指针为head,
//由于没有分配新的结点,其指针域为空NULL
return head;//返回头指针
}/*}}}*/
//链表判空
int is_empty_list(LinkNode *head)/*{{{*/
{
return head->next == NULL;
}/*}}}*/
//利用头插法在头指针前面插入一个新的结点
//*{{{*/
//在堆区分配一个新的空间
int insert_head_linklist(LinkNode *head,DataType data)
{
LinkNode *temp = NULL;
temp = (LinkNode *)malloc(sizeof(LinkNode ));
memset(temp,0,sizeof(LinkNode));//将新申请的空间手动清零
temp->data = data;
temp->next = head->next;
head->next = temp;
return 0;
}/*}}}*/
//利用尾插法在尾指针前面插入一个新的结点
//*{{{*/ /先分配一个新的结点(在堆区)
//在交换指针域
int insert_tail_linklist(LinkNode *head,DataType data)
{
LinkNode *temp = NULL;
LinkNode *p = NULL;
//在堆区分配一个新对空间,用temp保存申请空间对首地址
temp = (LinkNode *)malloc(sizeof(LinkNode ));
memset(temp,0,sizeof(LinkNode));//将新申请的空间手动清零
temp->data = data;//数据保存在分配对新空间内
//temp->next = NULL;可以直接将新分配的尾结点直接赋空
//下一步就是找到尾结点
p = head;
while(p->next)
{
p = p->next;//当p-》next指向的还不是空,即p不是尾结点时,
//p继续指向下一个结点,直到指向尾结点
}
//交换指针域,即在上一个尾结点后插入了一个新元素
temp->next = p->next;
p->next = temp;
return 0;
}/*}}}*/
//有序插入法,
int insert_order_linklist(LinkNode *head,DataType data)/*{{{*/
{
LinkNode *p = head;
LinkNode *temp = NULL;
temp = (LinkNode*)malloc(sizeof(LinkNode));
temp->data = data;
//遍历整个链表,找到插入位置前一结点
while(p->next)
{
if(p->next->data > data)//要插入的位置对数据比欲插入数据大则在
//该位置之前结点的后面插入
{
break;
}
p = p->next;
}
while(p->next && p->next->data > data)
{
temp->next = p->next;
p->next = temp;
}
}/*}}}*/
//删除整个链表
int delete_linklist(LinkNode *head)/*{{{*/
{
}
/*}}}*/
//打印链表
int print_linklist(LinkNode *head)/*{{{*/
{
LinkNode *lklst = NULL;
lklst = head->next;
//while(lklst != NULL)
while(lklst)
{
printf("%-5d",lklst->data);
lklst = lklst->next;
}
putchar('\n');
return 0;
}/*}}}*/
//链表逆置
int inverted_linklist(LinkNode *head)/*{{{*/
{
LinkNode *temp = head;
LinkNode *head_p = head;
LinkNode *p1 = NULL;
LinkNode *p2 = NULL;
LinkNode *p3 = head;
int i = 0;
//当链表为空链表时,无需逆置
if(is_empty_list(head))
{
return -1;
}
//当链表只有一个结点时,无需逆置
if(head->next->next == NULL)
{
return -1;
}
while(temp->next)
{
p1 = head;
while(p1->next->next)
{
p1 = p1->next;
}
p2 = p1->next;
p1->next = NULL;
p2->next = temp->next;
temp->next = p2;
temp = temp->next;
}
}
/*}}}*/
//链表按序排列
int order_linklist(LinkNode *head)/*{{{*/
{
LinkNode *max = NULL;
LinkNode *min = NULL;
int temp;
for(max = head->next;max != NULL;max = max->next)
{
for(min = max->next;min != NULL;min = min->next)
{
if(max->data < min->data)
{
// max->data ^= min->data;
// min->data ^= max->data;
// max->data ^= min->data;
temp = max->data;
max->data = min->data;
min->data = temp;
}
// printf("min = %p,min->next = %p\n",min,min->next);
}
}
}
/*}}}*/
//删除指定结点
int delete_linknode(LinkNode *head,int pos)/*{{{*/
{
//int pos = 0;
LinkNode *p = head;
LinkNode *temp = NULL;
int i = 0;
#if 0
printf("请输入要删除的结点数:");
getchar();
scanf("%d",&pos);
getchar();
printf("%d\n",pos);
#endif
while(i != pos -1)
{
p = p->next;
i++;
}
temp = p->next;
p->next = temp->next;
}/*}}}*/
//在函数参数中指定删除一个数,然后释放结点
int delete_num_node(LinkNode *head,int data)/*{{{*/
{
LinkNode *temp = NULL;
LinkNode *p = head;
while(p->next && p->next->data != data)
{
p = p->next;
}
if(p->next == NULL)
{
return -1;
}
temp = p->next;
p->next = p->next->next;
free(temp);
}/*}}}*/
//调用删除函数后手动输入需要删除的数据结点
int delete_num_node_byhand(LinkNode *head)/*{{{*/
{
int data = 0;
LinkNode *temp = NULL;
LinkNode *p = head;
print_linklist(head);
printf("请输入要删除的结点数:");
scanf("%d",&data);
printf("data = %d\n",data);
while(p->next && p->next->data != data)
{
p = p->next;
}
if(p->next == NULL)
{
return -1;
}
temp = p->next;
p->next = p->next->next;
free(temp);
}
/*}}}*/
code-3:main.c
#include "head.h"
int main()
{
long long i = 0;
LinkNode *head = NULL;
head = create_empty_linklist();
insert_tail_linklist(head,34);
insert_tail_linklist(head,45);
insert_tail_linklist(head,56);
insert_tail_linklist(head,67);
print_linklist(head);
insert_order_linklist(head,44);
insert_order_linklist(head,49);
print_linklist(head);
inverted_linklist(head);
print_linklist(head);
//insert_head_linklist(head,1);
insert_head_linklist(head,3);
insert_head_linklist(head,1);
print_linklist(head);
//getchar();
//printf("下面将链表按大小顺序排序\n");
print_linklist(head);
order_linklist(head);
print_linklist(head);
//getchar();
//delete_linknode(head,3);
//print_linklist(head);
delete_linknode(head,3);
print_linklist(head);
delete_num_node(head,3);
print_linklist(head);
delete_num_node_byhand(head);
print_linklist(head);
//delete_linknode(head);
//print_linklist(head);
return 0;
}