C语言磨磨蹭蹭的学了半个多月了,尝试自己写个链表,这里记录一下学习进度。
大致思想是先建立一个表头(header)然后通过表头指向节点链的第一个和最后一个元素,header的存在除了为了创建首节点方便另外附加记录链的长度以及其他信息的功能。表的功能有创建(creList),按数据或顺序查询对应节点(findNode)(lookNode),尾部添加(apNode)或在特定部位插入节点(inseNode),删除特定节点(delNode)或是拿走最后一个节点(popNode),以及展示(showList)和清空(pourList),清空功能的操作数1和0表示是否留下表头。
#include <stdio.h>
#include <stdlib.h>
typedef int Item;
typedef struct node{
Item data;
struct node* prior;
struct node* next;
}node;
typedef struct header{
int len;
struct node* first;
struct node* last;
}header;
static void terminate(const char* message);
header* creList(void);
node* findNode (header* lh, Item n);
node* lookNode (header* lh, int i);
void inseNode (header* lh, Item n, int i);
void apNode (header* lh, Item n);
void delNode (header* lh,node* np);
void popNode (header* lh);
void showList (header* lh);
void pourList (header* lh, int n);
int main(void)
{
header* march;
march = creList();
// function test
apNode(march,2);
apNode(march,3);
apNode(march,1);
apNode(march,9);
inseNode(march,4,2);
inseNode(march,7,0);
popNode(march);
delNode (march, findNode(march, 3));
delNode (march, lookNode(march, 2));
showList(march);
pourList(march, 1);
return 0;
}
static void terminate(const char* message)
{
printf("\n--%s--\n", message);
exit (EXIT_FAILURE);
}
header* creList(void)
{
header* lh = (header*)malloc(sizeof(header));
if (lh == NULL)
terminate("Error in create.");
lh->len = 0;
lh->first = NULL;
lh->last = NULL;
return lh;
}
node* findNode (header* lh, Item n)
{
node* p = lh->first;
for (p; p != NULL && n != p->data; p = p->next)
;
if (p != NULL && n == p->data)
return p;
puts("can not find");
return NULL;
}
node* lookNode (header* lh, int i)
{
node* p = lh->first;
int j = 0;
for (p; p != NULL && j < i; p = p->next)
j++;
if (p != NULL && j == i)
return p;
puts("wrong number");
return NULL;
}
void apNode (header* lh, Item n)
{
node* prev,* new_node;
prev = lh->last;
new_node = (node*)malloc(sizeof(node));
if (new_node == NULL){
puts("Databse Full, insert wrong");
free(new_node);
return;
}
new_node->data = n;
new_node->next = NULL;
new_node->prior = NULL;
if ( lh->len == 0){
lh->first = new_node;
lh->last = new_node;
lh->len ++;
puts("the first node had inserted");
return;
}else{
new_node->prior = prev;
prev->next = new_node;
lh->last = new_node;
}
lh->len ++;
}
void inseNode (header* lh, Item n, int i)
{
node* cur,* prev,* new_node;
int j = 0;
if ( lh->len == 0){
apNode (lh, n);
return;
}
new_node = (node*)malloc(sizeof(node));
if (new_node == NULL){
puts("Databse Full, insert wrong");
free(new_node);
return;
}
new_node->data = n;
new_node->next = NULL;
new_node->prior = NULL;
for (cur = lh->first, prev = NULL;
cur != NULL && j++ < i;
prev = cur, cur = cur->next)
;
if(prev != NULL){
prev->next = new_node;
new_node->prior = prev;
}else{
//puts("Insert in begin");
lh->first = new_node;
}
if (cur != NULL){
cur->prior = new_node;
new_node->next = cur;
}else{
//puts("node is in the end");
lh->last = new_node;
}
lh->len ++;
}
void popNode (header* lh)
{
node* cur,* prev;
if ( lh->len == 0 || lh->first == NULL){
puts("list emptied");
return;
}else if (lh->first == lh->last){
cur = lh->last;
lh->first = NULL;
lh->last = NULL;
free(cur);
}else{
cur = lh->last;
prev = cur->prior;
prev->next = NULL;
lh->last = prev;
free(cur);
}
lh->len --;
}
void delNode (header* lh,node* np)
{
node* post,* prev;
if (lh->len <= 1){
popNode (lh);
return;
}
post = np->next;
prev = np->prior;
if (post)
post->prior = prev;
else
lh->last = prev;
if (prev)
prev->next = post;
else
lh->first = post;
free(np);
(lh->len)--;
}
void showList (header* lh)
{
node* np;
np = lh->first;
while(np){
printf("%d", np->data);
np = np->next;
}
}
void pourList (header* lh,int n)
{
while((lh->last) != 0)
popNode (lh);
if(!n)
free(lh);
else
printf("\n%d node leave in list\n",lh->len);
}