链表
双向链表的结点是结构体,由数据本体(key),指向前一元素的指针(prev)和指向后一元素的指针(next)组成,这些结构体通过指针连接成一个链,形成了双向链表。
双向链表 的结点:
struct Node{
int key;
Node *prev,*next
};
另外,在表头设置了一个头结点,头结点不包含实际数据,让我们轻松对链表进行修改。
init函数用于初始化链表:
Node *nil;
void init()
{
nil = (Node *)malloc(sizeof(Node)); //动态申请指定大小的内存空间
nil->next = nil; //箭头运算符
nil->prev = nil;
}
insert函数用于生成包含所输入键值的结点,并将该结点插入表的开头
往双向链表中插入元素:
void insert(int key)
{
Node *x = (Node *)malloc(sizeof(Node));
x->key = key;
//在头结点后加入元素
x->next = nil->next;//将x与除了头结点的下一元素链接
nil->next->prev = x;// 下一元素向上链接
nil->next = x; //头结点向x元素链接
x->prev = nil; //x元素向上链接
}
listSearch函数用于搜索元素,可以在链表中寻找包含指定键值的结点,并返回其指针,假设cur为当前位置结点的指针,那么只要从头结点的next所指的结点,即链表开头元素开始逐个执行 cur = cur->next
,即可逐一访问每一个结点。
在双向链表中搜索元素:
Node *listSearch(int key)
{
Node *cur = nil->next;//从头结点后面的元素开始访问
while(cur != nil && cur->key != key) //找到key或者回到头结点时结束
{
cur=cur->next;
}
return cur;
}
deleteNode 函数会改变指针所指的位置,从而删除指定结点t。
从双向链表中删除元素:
void deleteNode(Node *t)
{
if( t == nil) return;//t为头结点时,不做处理
t->prev->next = t->next;
t->next->prev = t->prev;
free(t);//释放不需要的内存空间
}
void deleteNodeFirst()//删除第一个元素
{
deleteNode(nil->next);
}
void deleteNodeLast()删除最后一个元素
{
deleteNode(nil->prev);
}
void deleteKey(int key)//删除搜索到的元素
{
deleteNode(listSearch(key));
}