1.创建一个新的节点的函数
LTNode*BuyLTnode(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
if (newnode == NULL)
{
perror("malloc");
return NULL;
}
newnode->next = NULL;
newnode->prev = NULL;
newnode->data = x;
return newnode;
}
2.哨兵位的两个next,都初始化为了,链接自己的节点的next
LTNode* LTInit()
{
LTNode* phead = BuyLTnode(-1);//这个-1是给哨兵位的data的,把哨兵位data初始化成-1
phead->next = phead;
phead->prev = phead ;
return phead;
}
3.尾插先从head->prev,找到最后的一个位置
void LTPushBack(LTNode* phead, LTDataType x)
{
//LTInsert(phead, x);
assert(phead);
LTNode* tail = phead->prev;
LTNode* newphead = BuyLTnode(x);
tail->next = newphead;
newphead->prev = tail;
phead->prev = newphead;
newphead->next = phead;
4.头插,first先记录head的下一个节点,防止插入时把head的下一个节点地址替换弄没了
void LTPushPront(LTNode* phead, LTDataType x)
{
//LTInsert(phead->next, x);
assert(phead);
LTNode* newnode = BuyLTnode(x);
LTNode* first = phead->next;//注意此步
//空链表直接在哨兵位插入,为空的情况
phead->next = newnode;
newnode->prev = phead;
//不为空的情况
newnode->next = first;
first->prev = newnode;
}
5.尾删,phead->prev;找到尾并记录下来并free掉最尾节点,而且还要把尾的前一个节点记录下来记录到new里,再让哨兵位和新的节点new建立新的连接
void LTPopBack(LTNode* phead)
{
//LTErase(phead->prev);
assert(phead);
//没有数据只有哨兵位了,防止删了哨兵位
assert(!LTEmpty(phead));//bool相同返回来的是真,但在assert括号中!ture,不等于真。bool相同返回为真则判断为假。
LTNode* tail = phead->prev;
LTNode* new = tail->prev;
free(tail);
new->next = phead;
phead->prev = new;
}
6.头删把哨兵位后一个节点删掉,且哨兵位和第二节点建立新的连接
void LTPopPront(LTNode* phead)
{
//LTErase(phead->next);
assert(phead);
assert(!LTEmpty(phead));
LTNode* first = phead->next;
LTNode* second = first->next;
free(first);
phead->next = second;
second->prev = phead;
}
7.打印函数,从哨兵位的下一个节点开始打印
void LTPrint(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;//注意此步
printf("sentinel<==>");
while (cur != phead)
{
printf("%d<==>", cur->data);
cur = cur->next;
}
printf("\n");
}
8.寻找想查找的的值,pos->data == x就是要查找的节点
LTNode* LTFind(LTNode* pos, LTDataType x)//寻找想查找的的值
{
assert(pos);
LTNode* cur = pos->next;
while (cur != pos)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
9.在poss处之前插入,在寻找到处的前处插入,first先记录head的下一个节点,防止插入时把head的下一个节点地址替换弄没了,和头插原理相同
void LTInsert(LTNode* pos, LTDataType x)//在poss处之前插入,在寻找到处的前处插入
{
assert(pos);
LTNode* newnode = BuyLTnode(x);
LTNode* first = pos->prev;
pos->prev = newnode;
newnode->next = pos;
first->next = newnode;
newnode->prev = first;
}
10.删除poss处的节点
void LTErase(LTNode* pos)//删除poss处的节点
{
assert(pos);
LTNode* cur = pos;
LTNode* tail = pos->next;
LTNode* first = pos->prev;
free(cur);
tail->prev = first;
first->next = tail;
}
11.删除所有的节点
void LTDestroy(LTNode* phead)
{
LTNode* cur = phead->next;
while (cur != phead)
{
LTNode* next = cur->next;//保存下一个节点
free(cur);
cur = next;//下一个节点更新到cur,循环走起来
}
free(phead);
}
12.布尔值:布尔值:return phead->next == phead;若不相等返回为假,相等返回真。
12.2.assert(!LTEmpty(phead));assert不等于真。bool函数返回的值假在assert括号中就是真就不会触发assert, bool函数返回值真在assert括号中就是假就触发asser。12. 3.为在头删和尾删的函数使用为了防止哨兵位被删掉了
bool LTEmpty(LTNode* phead)
{
assert(phead);
return phead->next == phead;//相同返回的真:ture
}