引言
对于释放空间和删除元素,都还有些问题,希望能够得到评论提示。
链表元素(结构体)
想保存的值和前元素、后元素指针
struct Node
{
int val;
Node * next;
Node * prev;
};
链表的创建
先创建一个头结点指针,然后构建创建函数,以头结点指针为参数并返回指针对象
int main()
{
Node * head = (Node *)malloc(sizeof(Node));
head->next = NULL;
head->prev = NULL;
head->val = 10;
head = Create(head);
由于我是在C++在线编译器上做的操作,输入不便,因此选择用循环直接输入是个9个数来完成创建。
在这里,我把q始终作为尾结点看待,为当前节点元素申请空间,并赋值,使其的后对象指针始终指向头结点head,前对象指针指向前对象p。
把p作为倒数第二个节点看待,p的后对象指针始终指向当前对象q,头结点的前对象指针也始终指向当前对象q。
Node * Create(Node * head)
{
int i = 9;
Node * p,* q;
p = head;
for(;i > 0;i--)
{
q = (Node *)malloc(sizeof(Node));
q->val = i;
q->next = head;
q->prev = p;
p->next = q;
head->prev = q;
p = q;
}
return head;
}
双向链表的最初两个元素的关系就像下图所示
接下来就是插入后续元素,选用的是后插法,原理同上
链表的显示(遍历)
循环遍历输出了所有元素对象,函数和结果如下图
void Show(Node * head)
{
Node * c = head;
cout << "当前数:" << c->val << endl;
cout << "上一个数:" << c->prev->val << endl;
cout << "下一个数:" << c->next->val << endl;
c = c->next;
do
{
cout << "当前数:" << c->val << endl;
cout << "上一个数:" << c->prev->val << endl;
cout << "下一个数:" << c->next->val << endl;
c = c->next;
}
while(c != head);
return;
}
链表的排序
使用的是冒泡排序,其中有个理解小错误,写的过程中发现了,也展示出来大家看看。
//冒泡排序
Node * Sort(Node * head)
{
bool changeflg = true;
while(changeflg)
{
changeflg = false;
Node * p = head;
for(;p->next != head;p = p->next)
//只能走到倒数第二个元素,尾节点并不在循环中
{
if(p->val > p->next->val)
{
//交换其中的值
int temp;
temp = p->val;
p->val = p->next->val;
p->next->val = temp;
changeflg = true;
}
}
/*
//当前p处于尾节点,再进行比较
if(p->val > p->next->val)
{
//交换其中的值
int temp;
temp = p->val;
p->val = p->next->val;
p->next->val = temp;
changeflg = true;
}
*/
//这里刚开始有错误的理解,以为没有进行比较
//其实已经作为p->next进行过比较了
}
return head;
}
链表的插入(头插)
使用的是头插,由于是双向链表,很快就可以找到尾节点,其实也可以快速实现尾插;但如果是单向链表,需要先通过遍历找到尾节点,所以建议使用头插。
Node * Add(Node * head)
{
Node * q = (Node *)malloc(sizeof(Node));
q->val = 11;
//这里的顺序很重要,不然会丢失节点
q->next = head->next;
q->prev = head;
head->next->prev = q;
head->next = q;
return head;
}
按照1,2,3,4四个步骤建立链
链表的删除(按值删除)
遍历查找是否值相等,只适用于唯一值情况。如若删除所有重复值,需另写
void Delete(Node * head,int val)
{
Node * p = head;
Node * n = NULL;
for(;p->next != head;p = p->next)
{
if(p->val == val)
{
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
return;
}
}
//尾节点也得判断
if(p->val == val)
{
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
}
return;
}
链表的清除
注意需要释放掉曾经申请的内存
Node * Clear(Node * head)
{
Node * p = head;
Node * n = head->prev;
while(p->next != head)
{
Node * q = p->next;
free(p);
p = q;
}
free(n);
head = NULL;
return head;
}