单向链表
单向链表的每一个结点都用一个结构表示,该结构由数据和指向该结构的指针组成。
*一个double类型的单向链表结点
typedef struct node
{
double info;
struct node *next;
}node;
*一个自定义数据类型的单向链表结点
typedef struct Book
{
char *title;
char *author;
char *publisher;
int month_of_publication;
int year_of_publication;
int pages;
int price;
int edition;
}Book;
typedef struct A_Node_Of_Book_List
{
Book book_of_this_node;
struct A_Node_Of_Book_List *nextbookaddress;
}A_Node_Of_Book_List;
双向链表
typedef struct node
{
int info;
struct node *next;
struct node *prev;
}node;
typedef struct A_Node_Of_Book_List
{
Book book_of_this_node;
struct A_Node_Of_Book_List *nextbookaddress;
struct A_Node_Of_Book_List *prevbookaddress;
}A_Node_Of_Book_List;
循环链表
在循环链表中,最后一个结点的next指针指向第一个结点
typedef struct node
{
int info;
struct node *next;
};
如何在单向链表的末尾插入一个结点
*为新结点分配空间
*检查该结点是否为第一个结点
node* push_back(node *last,int info)
{
//如果这是第一个结点
if(last==NULL)
{
//为这个新结点创建内存空间
last = (node *)malloc(sizeof(node));
last->data = info;
last->next = NULL;
//返回链表尾部
return last;
}
//如果它不是第一个结点
else
{
//创建新结点
node *p = (node *)malloc(sizeof(node));
if(p) //检查该结点的内存空间是否可用
{
//最后一个结点变为p
last->next = p;
p->data = info;
p->next = NULL;
}
//返回链表的末尾
return p;
}
}
如何在单向链表首部插入结点
node* push_front(node *h,int info)
{
//为新结点分配内存
node *p = (node *)malloc(sizeof(node));
//将链表原来的头结点赋给next指针
p->next = h;
p->data = info;
return p;
}
如何得到单向链表的第一个元素
int front_element(node *h)
{
return first(h)->data;
}
node* first(node *h)
{
return h;
}
如何得到单向链表的最后一个元素
int back_element(node *h)
{
return last(h)->data;
}
node* last(node *h)
{
node *p=h;
for( ;p->next!=NULL;p=p->next)
return p;
}
遍历单向链表
void display(node *h)
{
node *p = h;
for( ;p!=NULL;p=p->next)
printf("Value = %d Address %u Next Address %u\n",p->data,p,p->next);
}
计数单向链表中结点的个数
int count(node *h)
{
int numberofnodes = 0;
node *p = h;
if(p==NULL)
return 0;
else
{
for( ;p!=NULL;p=p->next)
numberofnodes++;
return numberofnodes;
}
}
如何得到单向链表中数据项的频率
//函数返回特定元素的频率
int frequency(node *h,int value)
{
int freq = 0;
node *p = h;
for( ;p!=NULL;p=p->next)
if(p->data==value)
freq++;
return freq;
}
如何搜索单向链表中特定的数据项
//函数返回变量s在链表中的位置
int searchindex(node *h,int s)
{
int search_status = NOTFOUND;
int c = 0;
node *p = h;
for( ;p!=NULL;p=p->next)
{
c++;
if(p->data==s)
{
search_status = FOUND;
break;
}
if(search_status == FOUND)
return c;
else
//数据项未找到,返回不可能的位置-1
return -1;
}
}
如何得到单向链表中特定结点的地址
//函数返回特定位置变量的地址
node* get_address(node *h,int index)
{
node *p = h;
int c = 0;
for( ;p!=NULL;p=p->next)
{
c++;
if(c==index)
break;
}
return p;
}
如何在单向链表的特定位置后插入节点
node* insert(node *h,int location,int info)
{
int c = 0;
node *p = h;
node *r = p;
node *q = (node *)malloc(sizeof(node *));
if(location<count(h))
{
for( ;p!=NULL;p=p->next)
{
c++;
if(c==location)
break;
}
q->next = p->next;
p->next = q;
q->data = info;
}
return r;
}
如何得到单向链表的最大元素
int findmax(node *h)
{
node *p = h;
int max = p->data;
while(p!=NULL)
{
if(p->data>max)
max = p->data;
p = p->next;
}
return max;
}
如何得到单向链表的最小元素
int findmin(node* h)
{
node *p = h;
int min = p->data;
while(p!=NULL)
{
if(p->data<min)
min = p->data;
p = p->next;
}
return min;
}
使用给定值编辑特定结点的内容
node* replace(node *h,int location,int info)
{
int c = 0;
node *p = h;
node *r = p;
node *q = (node *)malloc(sizeof(node *));
if(location<count(h))
{
for( ;p!=NULL;p=p->next)
{
c++; //increase the count
if(c==location-1)
break;
}
q = p->next;
q->next = p->next->next;
q->data = info;
}
//返回头结点指针
return r;
}
//根据位置得到结点的值
int get_value(node* h,int index)
{
int c = 0;
node *p = h;
for( ;c<=index;c++)
p = p->next;
return p->data;
}
合并两个链表
例链表 11=12,13,14,15 12=16,17,18,19
如果想要合并成12,13,18,19 则merge(11,12,1,2,3,4)
如果想要合并成12,13,14,15,16,17,18,19 则merge(11,12,1,count(11),1,count(12))
node* merge(node *list_1,node *list_2,int start_1,int finish_1,int start_2,int finish_2)
{
int i;
node *p,*q;
p = push_back(p,get_value(list_1,start_1));
q = p;
for(i=start_1+1;i<=finish_1;i++)
p = push_back(p,get_value(list_1,i));
for(i=start_2;i<=finish_2;i++)
p = push_back(p,get_value(list_2,i));
return q;
}