目录
[2.1 在栈上申请空间(init接口实现初始化)](#2.1 在栈上申请空间(init接口实现初始化))
[2.2 头插接口实现](#2.2 头插接口实现)
[2.3 带头指针链表任意位置插入](#2.3 带头指针链表任意位置插入)
[2.4 带头指针链表删除元素](#2.4 带头指针链表删除元素)
[2.5 带头指针链表遍历](#2.5 带头指针链表遍历)
[2.6 销毁元素](#2.6 销毁元素)
一、带头指针的链表头结构
C
// 链表头结构
typedef struct
{
Node_t *header;
int count;
}ChainList_t;
二、接口的设计与实现
C
void initChainList(ChainList_t *table);
void destroyChianList(ChainList_t *table);
int insertChainLiHeader(ChainList_t *table,Element_t val);
int insertChainListPos(ChainList_t *table,int pos,Element_t val);
int deleteChainListElement(ChainList_t *table,Element_t val);
void showChianList(const ChainList_t *table);
2.1 在栈上申请空间(init接口实现初始化)
C
void initChainList(ChainList_t* table)
{
table->count = 0;
table->header = NULL;
}
2.2 头插接口实现
带头指针的链表:引入dummy作为虚拟头结点,简化操作
C
int insertChainLiHeader(ChainList_t* table, Element_t val)
{
Node_t dummy;
dummy.next = table->header; // 指针赋值
//下同,dummy作为虚拟头节点
Node_t *p = &dummy;
Node_t *new_node = malloc(sizeof(Node_t));
if (new_node == NULL)
{
return -1;
}
// 初始化
new_node->val = val;
// 节点插入逻辑
new_node->next = p->next;
p->next = new_node;
++table->count;
table->header = dummy.next; //临时dummy存的值,最后要赋值给头指针
return 0;
}
2.3 带头指针链表任意位置插入
C
int insertChainListPos(ChainList_t* table,int pos, Element_t val)
{
Node_t dummy;
dummy.next = table->header;
// 边界值
if (pos < 0 || pos > table->count)
{
printf("insert pos invalid\n");
return -1;
}
Node_t *p = &dummy;
int index = -1;
while (index < pos-1) // index == pos-2、p = p->next退出while
{
p = p->next;
++index;
}
if (p == NULL)
{
return -1;
}
Node_t *new_node = malloc(sizeof(Node_t));
new_node->val = val;
new_node->next = p->next;
p->next = new_node;
++table->count;
table->header = dummy.next;
return 0;
}
2.4 带头指针链表删除元素
C
int deleteChainListElement(ChainList_t* table, Element_t val)
{
Node_t dummy;
dummy.next = table->header;
Node_t *p = &dummy;
while (p->next && p->next->val != val)
{
p = p->next;
}
if (p->next == NULL)
{
printf("not find\n");
return -1;
}
Node_t *tmp = p->next;
p->next = tmp->next;
free(tmp);
--table->count;
table->header = dummy.next;
return 0;
}
2.5 带头指针链表遍历
C
void showChianList(const ChainList_t* table)
{
// p指向第一个节点(比如100)
Node_t *p = table->header;
printf("chainlist : %d Element\n",table->count);
while (p)
{
printf("%d\t",p->val);
p = p->next;
}
printf("\n");
}
2.6 销毁元素
销毁该链表的元素区域,头不管(在堆上申请的空间才需要手动申请和释放)
C
void destroyChianList(ChainList_t *table)
{
Node_t dummy;
dummy.next = table->header;
Node_t *p = &dummy;
Node_t *tmp;
while (p->next)
{
tmp = p->next;
p->next = tmp->next;
free(tmp);
--table->count;
}
printf("chainlist have : %d element",table->count);
}
三、test测试例
C
int test02()
{
ChainList_t table1; //表在栈上
initChainList(&table1); //进行初始化,而非创建新表
for (int i=0;i<10;i++)
{
insertChainLiHeader(&table1,i+200);
}
insertChainListPos(&table1,8,7000);
showChianList(&table1);
deleteChainListElement(&table1,200);
showChianList(&table1);
destroyChianList(&table1);
}

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!
