C语言链表练习

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);
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值