新人小白,初学代码。本博客简单的说一下自己学链表的心得,如有错误,欢迎指出。
链表是一种常见的基础数据结构,可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。 作为有强大功能的链表,对他的操作当然有许多,比如:链表的创建,修改,删除,插入,输出,排序,反序,清空链表的元素,求链表的长度等等。
#include
#include
#include
#define TYPE int
typedef struct Node
{
TYPE data;
struct Node* next;
}Node;
typedef struct List
{
Node* head;
Node* tail;
size_t size;
}List;
Node* creat_node(TYPE data)
{
Node* node = malloc(sizeof(Node));//获取内存
node->data = data;
node->next = NULL;//初始化
return node;
}
List* creat_list(void)
{
List* list = malloc(sizeof(List));
list->head = NULL;
list->tail = NULL; //初始化
}
下面讲讲链表的几个功能
void head_add_list(List* list,TYPE data)
{
Node* node = creat_node(data);
if(0 == list->size)
{
list->head = node;
list->tail = node;//当链表的size为零时,头部添加就是将head和tail变成node
}
else
{
node->next = list->head;//将node的next指针指向原头部
list->head = node;//将链表的头部指针指向node
}
list->size++;//头部添加完成后将size++
}
void tail_add_list(List* list,TYPE data)//尾部添加就是和头部反一下
{
Node* node = creat_node(data);
if(0 == list->size)
{
list->head = node;
list->tail = node;
}//当size为零时,链表就没有头尾之分了,所以和头添加一样,将node放进去就好了
else
{
list->tail->next = node;
list->tail = node;
}将原尾部的next指向node,在将list的tail指向node就可以将node变成尾部。
list->size++;//添加数后将size++
}
bool head_del_list(List* list)
{
if(0 == list->size)return false;//当size为0时就没有可以删除的啦,所以返回false
Node* node = list->head;
if(1 == list->head);//当size为1时,头删除就是将唯一的数删掉
{
list->head = NULL;
list->tail = NULL;//将头部和尾部全部指向空指针
}
else
{
list->head = node->next;//将链表头部指向要删除的node的下一个数
}
free(node);//释放node
list->size--;//删除一个数就要将size--
return true;
}
void destory_list(List* list)
{
while(0<list->size)
{
head_dal_list(list);
}
free(list);
}
bool tail_dal_list(List* list)
{
if(0 == list->size)return false;//当size为0就没什么好删除的啦,返回false
Node* node = list-tail;
if(1 == list->size)
{
list->tail = NULL;
list->tail = NULL;//当size为1时,就把唯一的数删除,将tail和head全指向NULL就好了
}
Node* prev = list->head;
while(prev->next != list->tail)
{
prev = prev->next;
}//通过while循环找到尾部的前一个值
free(list->tail);//释放尾结点
list->tail = prev;
prev->next = NULL;
list->size--;//删除一个数后size--
return true;
}
bool insert_list(List* list,int index,TYPE data)
{
if(index < 0 || index >= list->size)return false;//当插入的位置不存在时返回false
if(0 == index)
{
head_add_list(list,data);
}
else
{
Node* prev = list->head;
for(int i=0;i<index-1;i++)
{
prev = prev->next;
}//通过for循环找到要插入位置的上一个结点
Node* node = creat_node(data);
node->next = prev->next;
prev->next = node;
}
list->size++;//插入一个数也要size++
return true;
}
bool del_index_list(List* list,int index)
{
if(index < 0 || index >list->size)return false;//当删除的数的位置不存在时,返回false
if(0 == index)return head_del_list(list);
if(list->size-1 == index)return tail_del_list(list);//当要删的是头和尾时可以直接调用前面的头删除和尾删除
Node* prev = list->head;
for(int i=0;i<index-1;i++)
{
prev = prev->next;
}//用for循环找到要删除位置的前一个结点
Node* node = prev->next;
prev->next = node->next;
free(node);
list->size--;
return true;
}
bool del_value_list(List* list,TYPE data)
{
if(data == list->head->data)
{
head_del_list(list);
return true;
}//当头部的数据和要删的一样就可以直接调用前面的头部删除函数
Node* prev = list->head;
while(NULL != prev->next)
{
if(data == prev->next->data)//通过while循环找到要删除的值的前一个结点
{
Node* node = prev->next;
prev->next = node->next;
free(node);
list->size--;//删除后要size--
return true;
}
prev = prev->next;
}
return false;
}
void show_list(List* list)
{
for(Node* node=list->head;NULL != node;node->next)
{
printf("%d ",node->data);
}//通过for循环让node从头部开始一直到尾部,让获取到尾结点后的NULL就停止然后换行
printf("\n");
}
//此函数用的是冒泡排序法(在主函数中别忘记遍历)
void sort_list(List* list)
{
for(Node* i = list->head;i->next != NULL;i=i->next)
{
for(Node* j = i->next;j->next!= NULL;j=j->next)//通过for循环获取i结点和j结点
{
if(i->data>j->data)
{
TYPE data = i->data;
i->data = j->data;
j->data = data;
}//当获取到i结点的值比j的大时,将ij的值互换。通过ij两个指针将链表的值从小到大排序
}
}
}
//逆序就是从大到小排序,相当于上一个函数的反函数(逆序英文不会就用拼音代替啦)
//(在主函数中别忘了遍历)
void nixu(List* list)
{
Node* p1 = list->head;
Node* p2 = p1->next;
Node* p3 = NULL;//定义三个结点
list->tail = p1;//将尾结点指向p1
p1->next = NULL;//p1的next指向空
while(p2)
{
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}//通过while循环将p1p2p3的值逆序排列
list->head = p1;
}
以上就是我最近学习链表的内容以及心得,欢迎指出错误和优化代码
谢谢