最近学习了数据结构,在写代码时才开始将头文件与实现以及测试用的主函数分开写,逐渐开始理解封装的意义所在,为用户留出一个接口使用,而用户并不知道具体的实现。这里写了一个单链表,我的理解就是单链表就是由一个一个结点连起来的,这里你可以使用一个新的结点指向这个链表的第一个结点,那么这个结点就称为头结点。
代码实现如下(备注:这里将头文件,实现文件,以及主函数分开来写的)
//头文件LinkList.h
#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_
#define ERROR -1
typedef int elem_type;
typedef struct _NODE
{
elem_type data;
struct _NODE *next;
}NODE;
bool init_link_list(NODE *phead);
bool destory_link_list(NODE *phead);
NODE *init_link_list_ex();
bool destory_link_list_ex(NODE *phead);
bool is_empty(NODE *phead);
int get_length(NODE *phead);
bool show(NODE *phead, void (*pfunc)(elem_type *));
bool insert_head(NODE *phead,elem_type e);
bool insert_tail(NODE *phead,elem_type e);
bool insert(NODE *phead,int pos,elem_type e);
bool delete_head(NODE *phead,elem_type *e);
bool delete_tail(NODE *phead,elem_type *e);
bool del(NODE *phead,int pos, elem_type *e);
bool sort(NODE *phead);
NODE *meger(NODE *pheadA,NODE *pheadB);//两个有序链表合并为一个有序链表
NODE *rev_link_list_one(NODE *phead);
#endif
<pre name="code" class="cpp">//实现LinkList.cpp
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include"LinkList.h"
bool init_link_list(NODE *phead)
{
if (phead == NULL)
{
return false;
}
phead->next = NULL;
return true;
}
bool delete_head(NODE *phead,elem_type *e)
{
if (phead == NULL || is_empty(phead))
{
return false;
}
NODE *p = phead->next;
phead->next = p->next;
*e = p->data;
free(p);
return true;
}
bool destory_link_list(NODE *phead)
{
if (phead == NULL || is_empty(phead))
{
return false;
}
elem_type tmp;
while(!is_empty(phead))
{
delete_head(phead, &tmp);
}
phead->next = NULL;
return true;
}
NODE *init_link_list_ex()
{
NODE *phead = (NODE *)malloc(sizeof(NODE));
assert( phead != NULL);
phead->data = 0;
phead->next = NULL;
return phead;
}
bool destory_link_list_ex(NODE *phead)
{
if (phead == NULL || is_empty(phead))
{
return false;
}
elem_type tmp;
while(!is_empty(phead))
{
delete_head(phead, &tmp);
}
phead->next = NULL;
free(phead);
return true;
}
bool is_empty(NODE *phead)
{
return phead->next == NULL;
}
int get_length(NODE *phead)
{
if (phead == NULL || is_empty(phead))
{
return ERROR;
}
int count = 0;
NODE *p = phead->next;
while(p != NULL)
{
p = p->next ;
count++;
}
return count;
}
bool show(NODE *phead, void (*pfunc)(elem_type *))
{
if (phead == NULL || is_empty(phead))
{
return false;
}
NODE *p = phead->next;
while( p != NULL)
{
pfunc(&p->data);
p = p->next;
}
printf("\n");
return true;
}
static NODE *alloc_node(elem_type e)
{
NODE *tmp = (NODE *)malloc(sizeof(NODE));
if (tmp == NULL)
{
return false;
}
tmp->data = e;
tmp->next = NULL;
return tmp;
}
bool insert_head(NODE *phead,elem_type e)
{
if (phead == NULL)
{
return false;
}
NODE *tmp = alloc_node(e);
tmp->next = phead->next;
phead->next = tmp;
return true;
}
bool insert_tail(NODE *phead,elem_type e)
{
if (phead == NULL)
{
return false;
}
NODE *tmp = alloc_node(e);
NODE *p = phead;
while( p->next != NULL)
{
p = p->next;
}
p->next = tmp;
return true;
}
bool insert(NODE *phead,int pos,elem_type e)
{
if (phead == NULL || pos<0 || pos>get_length(phead) || is_empty(phead))
{
return false;
}
NODE *p = phead;
NODE *tmp = alloc_node(e);
for( int i=0;i<pos;i++)
{
p = p->next;
}
tmp->next = p->next;
p->next = tmp;
return true;
}
bool delete_tail(NODE *phead,elem_type *e)
{
if (phead == NULL || is_empty(phead))
{
return false;
}
NODE *p = phead;
while( p->next->next != NULL)
{
p = p->next;
}
*e = p->next->data;
free(p->next);
p->next = NULL;
}
bool del(NODE *phead,int pos, elem_type *e)
{
if (phead == NULL || pos<0 || pos>get_length(phead) || is_empty(phead))
{
return false;
}
NODE *s = phead;
NODE *p = phead->next;
for(int i=0;i<pos;i++)
{
s = p;
p = p->next;
}
*e = p->data;
s->next = p->next;
free(p);
return true;
}
bool sort(NODE *phead)
{
if (phead == NULL || is_empty(phead))
{
return false;
}
NODE *p = phead->next;
NODE *s = p;
for (int j=0;j<get_length(phead);j++)
{
for(int i=0;i<get_length(phead)-1-j;i++)
{
if( p->data > p->next->data)
{
int tmp = p->next->data;
p->next->data = p->data;
p->data = tmp;
}
p = p->next;
}
p = s;
}
return true;
}
NODE *meger(NODE *pheadA,NODE *pheadB)//两个有序链表合并为一个有序链表
{
if (pheadA == NULL || pheadB == NULL || is_empty(pheadA) || is_empty(pheadB))
{
return false;
}
NODE *p = pheadA->next;
NODE *s = pheadB->next;
NODE *pheadC = alloc_node(0);
NODE *r = pheadC;
NODE *tmp;
while( p != NULL && s != NULL)
{
if( p->data <= s->data)
{
tmp = alloc_node(p->data);
r->next = tmp;
r = tmp;
p = p->next;
}
else
{
tmp = alloc_node(s->data);
r->next = tmp;
r = tmp;
s = s->next;
}
}
while( p != NULL)
{
tmp = alloc_node(p->data);
r->next = tmp;
r = tmp;
p = p->next;
}
while( s != NULL)
{
tmp = alloc_node(s->data);
r->next = tmp;
r = tmp;
s = s->next;
}
return pheadC;
}
NODE *rev_link_list_one(NODE *phead)
{
NODE *p = phead->next;
NODE *pheadA = alloc_node(0);
NODE *s = pheadA;
while( p != NULL)
{
insert_head(s,p->data);
p = p->next;
}
return pheadA;
}
<pre name="code" class="cpp">//主函数,为了测试每个函数的正确性,所以每个都测了一遍
#include"LinkList.h"
#include<stdio.h>
#include<vld.h>
void print_int(elem_type *e)
{
printf("%d ",*e);
}
int main()
{
NODE headA;
init_link_list(&headA);
insert_head(&headA,9);
insert_head(&headA,20);
insert_head(&headA,30);
insert_head(&headA,8);//8,30,20,9
show(&headA,print_int);
insert_tail(&headA,50);//8,30,20,9,50
insert(&headA,3,90);//8,30,20,90,9,50
show(&headA,print_int);
int tmp = 0;
delete_head(&headA,&tmp);//30,20,90,9,50
show(&headA,print_int);
delete_tail(&headA,&tmp);//30,20,90,9
show(&headA,print_int);
del(&headA,1,&tmp);//30,90,9
printf("链表A:\n");
show(&headA,print_int);
NODE headB;
init_link_list(&headB);
insert_head(&headB,10);
insert_head(&headB,2);
insert_head(&headB,90);
insert_head(&headB,40);//40,90,2,10
printf("链表B:\n");
show(&headB,print_int);
printf("排序后的链表A\n");
sort(&headA);
printf("排序后的链表B\n");
sort(&headB);
show(&headA,print_int);
show(&headB,print_int);
NODE *p = meger(&headA,&headB);
NODE *s = rev_link_list_one(&headB);
printf("合并后的链表\n");
show(p,print_int);
printf("逆置后的后的链表B\n");
show(s,print_int);
destory_link_list(&headA);
destory_link_list(&headB);
destory_link_list_ex(s);
destory_link_list_ex(p);
return 0;
}
以上就是单链表的全部内容了,仅供参考,希望大家提出建议。