书上是返回当前结点,但是这样头插和尾插的前驱会是null,所以为了在一个程序里实现头插,尾插,随便插的功能,我返回了其前驱,然后插入时用if进行选的插入的方法,也许返回当前结点也可以插入,但我还是没有想到来着,啊哦,哈?
#include<stdio.h> // pirntf; scanf;
#include<stdlib.h> // malloc free exit
#include<assert.h> // assert;
#include<string.h>
typedef int elemtype;
typedef struct listnode
{
elemtype data;
struct listnode* prev;
struct listnode* next;
}listnode;
typedef struct
{
struct listnode* head;
int cursize;
}dulinklist;
static listnode* buynode()
{
listnode* s = (listnode*)malloc(sizeof(listnode));
if (nullptr == s) exit(1);
memset(s, 0, sizeof(listnode));
return s;
}
static void freenode(listnode* p)
{
free(p);
p = nullptr;
}
void init_list(dulinklist* plist)
{
assert(plist != nullptr);
plist->head = buynode();
plist->cursize = 0;
}
void print_list(dulinklist* plist)
{
assert(plist != nullptr);
listnode* p = plist->head->next;
while (p != nullptr)
{
printf("%4d", p->data);
p = p->next;
}
printf("\n");
}
int getsize(dulinklist* plist)
{
assert(plist != nullptr);
return plist->cursize;
}
bool is_empty(dulinklist* plist)
{
assert(plist != nullptr);
return plist->cursize == 0;
}
listnode* findvalue(dulinklist* plist, elemtype val)
{
assert(plist != nullptr);
listnode* p = plist->head->next;
while (p != nullptr && p->data != val)
{
p = p->next;
}
return p;
}
listnode* findpos(dulinklist* plist, int pos)
{
assert(plist != nullptr);
if (pos<1 || pos>plist->cursize+1) return nullptr;
listnode* p = plist->head;
int i = 1;
while (i < pos)
{
p = p->next;
++i;
}
return p;
}
void insert(dulinklist* plist, listnode* p, elemtype val)
{
listnode* s = buynode();
if (p->next == nullptr)
{
s->data = val;
s->next = p->next;
s->prev = p;
p->next = s;
plist->cursize += 1;
}
else
{
s->data = val;
s->next = p->next;
p->next->prev = s;
s->prev = p;
p->next = s;
plist->cursize += 1;
}
}
bool insert_item(dulinklist* plist, int pos, elemtype val)
{
assert(plist != nullptr);
listnode* p = findpos(plist, pos);
insert(plist, p, val);
return true;
}
void push_back(dulinklist* plist, elemtype val)
{
assert(plist != nullptr);
insert_item(plist, plist->cursize + 1, val);
}
void push_front(dulinklist* plist, elemtype val)
{
assert(plist != nullptr);
//insert(plist, plist->head, val);
insert_item(plist,1, val);
}
void insert_ar(dulinklist* plist, int pos, elemtype* ar, int n)
{
assert(plist != nullptr && ar != nullptr);
for (int i = 0; i < n; ++i)
{
insert_item(plist,pos, ar[i]);
}
}
void insert_val(dulinklist* plist, int pos, elemtype val, int n)
{
assert(plist != nullptr);
for (int i = 0; i < n; ++i)
{
insert_item(plist,pos, val);
}
}
void erase(dulinklist* plist, listnode* p)
{
assert(plist != nullptr && p != nullptr);
if (p->next == nullptr)
{
p->prev->next = p->next;
}
else
{
p->prev->next = p->next;
p->next->prev = p->prev;
}
freenode(p);
p = nullptr;
plist->cursize -= 1;
}
bool erase_pos(dulinklist* plist, int pos)
{
assert(plist != nullptr);
if (pos<1 || pos>plist->cursize) return false;
listnode* p = findpos(plist, pos);
p = p->next;
erase(plist, p);
}
void pop_back(dulinklist* plist)
{
assert(plist != nullptr);
erase_pos(plist, plist->cursize);
}
void pop_front(dulinklist* plist)
{
assert(plist != nullptr);
erase(plist, plist->head->next);
}
void remove(dulinklist* plist, elemtype val)
{
assert(plist != nullptr);
listnode* p = findvalue(plist, val);
erase(plist, p);
}
void clear_list(dulinklist* plist)
{
assert(plist != nullptr);
while (plist->cursize != 0)
{
erase(plist, plist->head->next);
}
}
void destroy_list(dulinklist* plist)
{
assert(plist != nullptr);
clear_list(plist);
freenode(plist->head);
plist->head = nullptr;
}
void remvoe_all(dulinklist* plist, elemtype val)
{
assert(plist != nullptr);
listnode* p = plist->head->next;
while (p != nullptr)
{
if (p->data == val)
{
erase(plist, findvalue(plist, val));
}
else
{
p = p->next;
}
}
}