链表类型
常用的链表类型
1、无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多的是作为其他数据结构的子结构,如哈希表、图的邻接表等。这两种结构在笔试面试种出现很多。
2、带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然复杂,但是使用代码实现后以后会发现结构带来了很多优势,实现反而简单了。
带头双向循环链表分析
带头双向循环链表结构:
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode *prev;
srtuct ListNode *next;
LTDataType data;
}LTNode;
带头双向循环链表的新节点创建:
LTNode* BuyLTNode(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
if (newnode == NULL)
{
perror("malloc fail");
return NULL;
}
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
带头双向循环链表的初始化:
LTNode* LTInit()
{
LTNode* phead = BuyLTNode(-1);
phead->next = phead;
phead->prev = phead;
return phead;
}
带头双向循环链表的尾插:
void LTPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* tail = phead->prev;
LTNode* newnode = BuyLTNode(x);
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
}
带头双向循环链表的头插:
void LTPushFront(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* newnode = BuyLTNode(x);
LTNode* first = phead->next;
phead->next = newnode;
newnode->prev = phead;
newnode->next = first;
first->prev = newnode;
}
带头双向循环链表的打印:
void LTPrint(LTNode* phead)
{
assert(phead);
printf("guard<==>");
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d<==>", cur->data);
cur = cur->next;
}
printf("%\n");
}