很早之前就想把自己学习数据结构的过程跟大家分享分享,那么现在开始吧。应该是大一开始学的数据结构,到现在也有几个年头了,也当是给自己复习下,总之听到数据结构的名字就给人一种很难学的感觉。
现在想想也没那么可怕,学习的时候把思路整理好,把代码调试通,数据结构不久被你搞定了么!好不扯了,开始正文。
单链表,数据结构的一种。我们用过数组,数组也是用来存储的,单链表这玩意跟它一样一样的。链表分为有头指针和没有头指针的,为了方便我写的是有头指针的!
- 1 单链表的初始化,先上代码
/**
* 初始化链表
*
* param ListNode * * head 双指针
*
* return void
*
*/
void ListInitiate(ListNode * * head)
{
* head = (ListNode *)malloc(sizeof(ListNode));
if (* head == NULL){
LOG("Hkesd_LOG:内存分配失败!\n");
exit (1);
}
(* head)->next = NULL;
LOG("Hkesd_LOG:链表初始化成功!\n");
}
初始化一个单链表,就是给链表的头指针分配内存。由于在初始化操作之前,头指针参数head没有具体的地址,在初始化操作时,头指针参数head才得到了具体的地址值,而这个地址值要返回出去,所以这里的头指针参数head设计成指针的指针类型。
- 2 单链表插入数据
/**
* 在链表中插入数据
*
* param ListNode * head 链表头指针
* param ElementType element 待插入的数据
*
* return int 1 插入成功
* 0 链表为空
*/
int ListInsert(ListNode * head, ElementType element)
{
if (head == NULL){
LOG("Hkesd_LOG:链表为空!\n");
return 0;
}
ListNode * tempNode = (ListNode *)malloc(sizeof(ListNode));
if (tempNode == NULL){
LOG("Hkesd_LOG:插入元素时分配内存失败\n");
exit(1);
}
tempNode->element = element;
tempNode->next = head->next;
head->next = tempNode;
return 1;
}
在链表中插入数据,这里的方法是头插法,就是一直在链表的头部插入,既然有头插法那么就有尾插法,还有你想往哪插就往哪插的方法,这里就不一一赘述了。
- 3 删除链表中的数据
/**
*
* 删除链表中的数据
*
* param ListNode * head 链表头指针
* param ElementType element 待删除的数据
*
* return int 1 删除成功
* 0 链表为空
*/
int ListDelete(ListNode * head, ElementType element)
{
ListNode * indexNode;
ListNode * tempNode;
if (head == NULL){
LOG("Hkesd_LOG:链表为空!\n");
return 0;
}
indexNode = head;
while (indexNode->next != NULL && indexNode->next->next != NULL && indexNode ->next-> element != element){
indexNode = indexNode->next;
}
tempNode = indexNode->next;
indexNode->next = indexNode->next->next;
free(tempNode);
return 1;
}
删除元素,无非就是找到元素然后删掉它。在链表中删除元素,有点名堂,因为这是单链表,你没办法知道待删除元素的前置节点在哪,所以就需要我们找到它的前置节点:
while (indexNode->next != NULL && indexNode->next->next != NULL && indexNode ->next-> element != element)
这句话的作用就是找到待删除元素的前置节点,其它的东西看代码就了解了。
- 4 撤销链表
/**
*
* 撤销单链表
*
* param ListNode * * head 链表头指针地址
*
* return void
*
*/
void ListDestory(ListNode * * head)
{
if (* head == NULL){
LOG("Hkesd_LOG:链表为空!\n");
return;
}
ListNode * firstTmepNode;
ListNode * secondTempNode;
firstTmepNode = * head;
while(firstTmepNode != NULL){
secondTempNode = firstTmepNode;
firstTmepNode = firstTmepNode->next;
free(secondTempNode);
}
* head = NULL;
}
因为单链表的节点空间是在程序运行时动态申请的,所以我们要手动回收内存(垃圾回收,这时我就默默的看着Java不说话)
- 5 最后我写了一个输出链表元素的函数
/**
*
* 输出单链表
*
* param ListNode * head 链表头指针
*
* return void
*
*/
void PrintList(ListNode * head)
{
if (head == NULL){
LOG("Hkesd_LOG:链表为空!\n");
return;
}
ListNode * tempNode;
tempNode = head->next;
printf("当前链表元素为:");
while(tempNode != NULL){
printf("%d ", tempNode->element);
tempNode = tempNode->next;
}
printf("\n");
}
链表写到这里,简单的东西也差不多了,写多了不说你们烦我自己都烦,把链表掌握,数据结构就掌握了一半了,后面的栈、队列甚者树都有链表的影子。
点一根烟,扶我起来写代码。