3.链表
3.1 链表的概念及结构
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表
中的指针链接次序实现的
注意:
1.从上图可看出,链式结构在逻辑上是连续的,但是在物理上不一定连续
2.现实中的结点一般都是从堆上申请出来的
3.从堆上申请的空间是按照一定的策略来分配的,两次申请的空间可能连续也可能不连续
3.2 链表的分类
1. 单向或者双向
2. 带头或者不带头
3. 循环或者非循环
3.3 单链表的实现
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;//元素类型
1.结点
typedef struct ListNode
{
SLDataType data;
struct ListNode* next;
}ListNode;
2.动态申请一个结点
ListNode* BuySListNode(SLDataType x)
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
assert(newnode!=NULL);
newnode->data = x;
newnode->next = NULL;
return newnode;
}
3.单链表打印
void SListPrint(ListNode* plist)
{
ListNode* cur = plist;
while (cur != NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
4.单链表尾插
void SListPushBack(ListNode** pplist, SLDataType x)
{
assert(pplist!=NULL);
ListNode* newnode = BuySListNode(x);
if (*pplist == NULL)//没有结点
{
*pplist = newnode;
}
else
{
ListNode* tail = *pplist;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
5.单链表的头插
void SListPushFront(ListNode** pplist, SLDataType x)
{
assert(pplist!=NULL);
ListNode* newnode = BuySListNode(x);
newnode->next = *pplist;
*pplist = newnode;
}
6.单链表的尾删
void SListPopBack(ListNode** pplist)
{
assert(pplist!=NULL);
assert(*pplist!=NULL);
if ((*pplist)->next == NULL)
{
free(*pplist);
*pplist = NULL;
}
else
{
ListNode* tailPrev = NULL;
ListNode* tail = *pplist;
while (tail->next != NULL)
{
tailPrev = tail;
tail = tail->next;
}
free(tail);
tailPrev->next = NULL;
}
}
7.单链表的头删
void SListPopFront(ListNode** pplist)
{
assert(pplist!=NULL);
assert(*pplist!=NULL);
ListNode* cur = (*pplist)->next;
free(*pplist);
*pplist = cur;
}
8.单链表查找
ListNode* SListFind(ListNode* plist, SLDataType x)
{
ListNode* p = plist;
while (p != NULL)
{
if (p->data == x)return p;
p = p->next;
}
return NULL;
}
9.把x插入到pos处
void SListInsert(ListNode** pplist, ListNode* pos, SLDataType x)
{
assert(pplist!=NULL);
assert(pos!=NULL);
// 头插
if (pos == *pplist)
{
SListPushFront(pplist, x);
}
else
{
ListNode* prev = *pplist;
while (prev->next != pos)
{
prev = prev->next;
}
ListNode* newnode = BuySListNode(x);
prev->next = newnode;
newnode->next = pos;
}
}
10.删除pos位置的值
void SListErase(ListNode** pplist,ListNode* pos)
{
assert(pplist != NULL);
assert(pos != NULL);
if (*pplist== pos)
{
SListPopFront(pplist);
}
else
{
ListNode* prev = *pplist;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
}
11.单链表在pos位置之后插入x
void SListInsertAfter(ListNode* pos, SLDataType x)
{
assert(pos != NULL);
ListNode* newnode = BuySListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
12.删除pos位置之后的值
void SListEraseAfter(ListNode* pos)
{
assert(pos != NULL);
if (pos->next == NULL)
return;
ListNode* q = pos->next;
pos->next = q->next;
free(q);
q = NULL;
}
13.单链表销毁
void SListDestory(ListNode* plist)
{
assert(plist != NULL);
while (plist->next!= NULL)
{
ListNode* q = plist->next;
plist->next = q->next;
free(q);
q = NULL;
}
free(plist);
}