双链表默认结构体
typedef struct DNode{
int data;
struct DNode* next;
struct DNode* prev;
}DNode;
1.采用头插尾插建立双链表
尾插
DNode* tail_create()
{
DNode*L=(DNode*)malloc(sizeof(DNode));
L->next=NULL;
L->prev=NULL;
DNode*r=L;
int x;
scanf("%d",&x);
while(x!=9999)
{
LNode*s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=NULL;
r->next=s;
s->prev=r;
r=s;
scanf("%d",&x);
}
return L;
}
思想:
先建立头节点,前指针后指针设为空
设置新节点r,把头节点赋值给r(目的是为了在后遍历时较为方便,将s节点赋值给r这样每次r都指向了最后一个节点(NULL前面那个))
进行数据的输入,若不为9999一直进行尾插,在循环里进行申请空间存储s节点,将数据赋值
因为尾插所以每次插入即为最后一个元素,因而每个s的next都指向空
建立s和前节点之间的next,prev
我们设置的r每次都是NULL前面一个节点,因而每次尾插s都在r后面,由此r->next=s;s->prev=r;
最后进行更新r将s给r
头插
DNode* head_create()
{
DNode*L=(DNode*)malloc(sizeof(DNode));
L->next=NULL;
L->prev=NULL;
int x;
scanf("%d",&x);
while(x!=9999)
{
DNode*s=(DNode*)malloc(sizeof(DNode));
s->data=x;
s->next=L->next;
if(L->next!=NULL)
{L->next->prev=s;}
L->next=s;
s->prev=L;
scanf("%d",&x);
}
return L;
}
思想:
循环同尾插
头插是将新的节点s插入到L的后面(所以我们不需要像尾插设立一个新节点r。)
因而s->next=L->next;
然后我们连接L->next的prev若L->next为空我们不需要建立prev所以需要进行判断是节点还是空。
最后我们连接s和L
L->next=s;
s->prev=L;
2.将带头结点双链表最小的元素移动到最前面
void move(DNode*&L)
{
DNode*pose=L,*p=L;
while(p->next!=NULL)
{
if(p->next->data<pose->next->data)
{
pose=p;
}
p=p->next;
}
LNode*r=pose->next;
pose->next=r->next;
if(r->next!=NULL)
r->next->prev=pose;
r->next=L->next;
L->next=r;
r->prev=L;
}
思想:
首先设置两个节点,均赋值为头节点(头节点不包含元素)。
我们用pose来保存最小值,利用p来进行遍历到最后一个节点。
如果pose->data大于p我们将p赋值给pose
注意pose->next才是我们找到的最小的节点因而设置为r
在将pose与r->next之间进行next,prev的相连
pose->next=r->next;r->next->prev=pose;
最后将r节点插入到头指针后,也就是L和L->next之间
r->next=L->next;L->next->prev=r;
最后连接L和r
L->next=r;r->prev=L:
3.一个带头结点的循环链表,反复查找最小的数不断输出直至为空
void del_min(DNode*&L)
{
while(L->next!=NULL)
{
DNode*pose=L,*p=L;
while(p->next!=NULL)
{
if(p->next->data<pose->next->data)
{pose=p;}
p=p->next
}
LNode*r=pose->next;
printf("%d",r->data);
pose->next=r->next;
r->next=prev;
free(r);
}
free(L);
}
思想:
因为要删除只剩空所以中止条件我们设置为头节点后若为空则中止
嵌入的函数是寻最小的数输出并释放,同2。(只是多了释放和打印)
最后释放头节点