数据结构(二):线性表之链式存储函数实现

线性表的链式存储的主要操作的实现:

注: 该链表包含头结点。

0. 头文件的宏定义:

#define SUCCESS    1
#define FAILED     0

typedef int Status;
typedef int dataType;

typedef struct node_{
	dataType  data;
	struct node_ *next;
}LinkNode_st, *LinkNode_pt;

1. 创建链表头:

    由于需要创建头结点,然后将头指针指向头结点,如果需要形参,需要传递头指针的地址。

/*      1.  链表的头结点创建     */

LinkNode_pt LinkList_create_head(LinkNode_pt *head)
{
    LinkNode_pt node;
	node= (LinkNode_pt)malloc(sizeof(LinkNode_st));
	if(!node) printf("malloc error\n");

    if(head)
        *head = node;
    return node;    /*函数调用结束后,malloc的空间不会释放,因此node的值可以作为返回值*/
}

2. 链表的插入:

/*
*     1 <= location <= length(linkList);
*/
Status LinkList_insert(LinkNode_pt head,  int location,  dataType data)
{
	LinkNode_pt  pcur = head;
	LinkNode_pt  node = NULL;
	int i = 1;
	if(!head){
		printf(" The LinkList ' head node is NULL \n");
		return FAILED;
	}

	if(location<=0) {
		printf("The location' value range is 1<= location <= LinkList_getLength(head) \n");
		return FAILED;
	}
	while(pcur &&  (i<location)){
		pcur = pcur->next;
		i++;
	}

	if(!pcur || i>location)
		printf("Location is out of range\n");

	node = (LinkNode_pt)malloc(sizeof(LinkNode_st));
	if(!node){
		printf("LinkList_insert : malloc error\n");
		return FAILED;
	}

	memcpy(&node->data, &data, sizeof(dataType));
	node->next = pcur->next;
	pcur->next = node;
	
	return SUCCESS;
	
}

3. 链表的删除:

/*
*   删除指定位置的节点:    1<= location <= length(linkList)
*/
Status  LinkList_delByLoc(LinkNode_pt  head,  int location,  dataType * data)
{
	LinkNode_pt pcur = head;
	LinkNode_pt node;
	int i = 1;

	if(!pcur){
		printf("The LinkList ' head node is NULL\n");
		return FAILED;
	}
	if(location<=0){
		printf("The location is out of range\n");
		return FAILED;
	}

	while(pcur && (i<location)){
		pcur = pcur->next;
		i++;
	}
	if(!pcur || (i>location)){
		printf("location is out of range\n");
		return FAILED;
	}

	node = pcur->next;
	memcpy(data, &node->data, sizeof(dataType));
	pcur->next =node->next;
	free(node);
	return SUCCESS;
		
}
/*
*   匹配某个数据的值,如果相等,则进行删除,cnt为删除的结点个数
*/
Status  LinkList_delByData(LinkNode_pt  head,  dataType * data, int cnt)
{
	LinkNode_pt pcur = head;
	LinkNode_pt node = NULL;

	if(!pcur){
		printf("The LinkList ' head node is NULL\n");
		return FAILED;
	}
	cnt = 0;
	
	while(pcur && pcur->next){
		if(!memcmp(data, &pcur->next->data, sizeof(dataType))){
			node = pcur->next;
			pcur->next = node->next;//1      跳过node节点
			cnt++;
			free(node);
			continue;
		}
		pcur = pcur->next;
	}
	
	if(!pcur ->next && !cnt){
		printf("This linkList doesn't have this node\n");
		return FAILED;
	}else{
		return SUCCESS;
	}
		
}

4.  获取指定位置节点的元素的值

Status LinkList_getElem(LinkNode_pt head,  int  location,  dataType data)
{
	LinkNode_pt pcur = head;
	LinkNode_pt node= NULL;
	int i = 1;

	if(!pcur){
		printf("This LinkNode ' head is NULL\n");
		return FAILED;
	}

	while(pcur->next && i<location){  /*可以不使用next*/
		pcur = pcur->next;
		i++;
	
	}

	if(!pcur->next){
		printf("This  location is out of range\n");
		return FAILED;
	}

	if(i == location){
		node = pcur->next;
		memcpy(&data, &node->data, sizeof(dataType));
		return SUCCESS;
	}else{
		return FAILED;
	}

}

5. 整个链表的创建(指定节点个数)

Status LinkList_create(LinkNode_pt *head,  int nodeNum)
{

	LinkNode_pt node;
	int i = 0;

	if(!head){
		printf("The head is NULL\n");
		return FAILED;
	}

	*head = (LinkNode_pt)malloc(sizeof(LinkNode_st));
	if(!*head){
		printf("LinkList_create : head node malloc error\n");
		return FAILED;
	}
	(*head)->next = NULL;

#ifdef TAILINSERT  //1 尾插法
	LinkNode_pt pcur, tail;
	pcur = *head;
	pcur->data = 0;
	pcur->next = NULL;
	tail = pcur;
	
	while(i<nodeNum){
		node = (LinkNode_pt)malloc(sizeof(LinkNode_st));
		if(!node){
			printf("LinkList_create: node malloc error\n");
			return FAILED; 
		}
		node->data = i+1;  /*可以修改*/
		node->next = NULL;
		
		tail->next = node;
		tail = node;	
		++i;
	}
#else  //1 头插法

	while(i<nodeNum){
		node = (LinkNode_pt)malloc(sizeof(LinkNode_st));
		if(!node){
			printf("LinkList_create: node malloc error\n");
			return FAILED; 
		}
		node->data = i+1;  /*可以修改*/
		node->next = (*head)->next;
		(*head)->next = node;	
		++i;
	}
#endif
	return SUCCESS;
}

6. 整个链表的删除:

/*
*  对于包含头结点的链表,空链表只有一个头结点和指向头结点的头指针
*  该函数删除有除最后一个节点外的所有节点,并将尾节点重新作为新的头节点
*/
Status LinkList_delete(LinkNode_pt *head)  /*未保留头结点*/
{

	if(!head){
		printf("The head is NULL\n");
		return FAILED;
	}
#ifdef  DOUBLE_POINTER   //1 只需维持一个指针,充分利用二级指针
	LinkNode_pt node;
	while(*head && (*head)->next){   /*当前节点和下一节点均不为空*/
		node = *head;
		*head = (*head)->next;       /*这个函数有点剑走偏锋,应该用Linus吐槽用二级指针时的那种*/
		free(node);
	}
	
	memset((*head)->data,0,sizeof((*head)->data));
#else   //1 维持两个指针
	LinkNode_pt p,q;
	int i=0;
	p = (*head)->next;
	
	while(p){
		q = p->next;
		free(p);
		p = q;
	}

	(*head)->next = NULL;

#endif
	return SUCCESS;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-05-18 14:53  叨陪鲤  阅读(61)  评论(0编辑  收藏  举报