记录一下写过的代码,
//list.h
#include <stdio.h>
//封装一个带头循环单链表
typedef struct Element{
int data;
//other field
} Element;
typedef struct Node{
Element elem;
struct Node * link;
}Node;
typedef Node * NodePointer;
void initList(NodePointer * plist);
int insertList(NodePointer * plist, const Element * e); //尾部插入
int deleteList(NodePointer * plist, const Element * e); //根据e删除一个节点
NodePointer invertList(NodePointer list);//反转一个链表
void destoryList(NodePointer * plist);
void showList(const NodePointer * plist);
//list.c
#include "list.h"
#include <stdlib.h>
#include <memory.h>
void initList(NodePointer * plist)
{
NodePointer pnode;
if(plist == NULL)
{
printf("initList error.\n");
exit(1);
}
pnode = (NodePointer)malloc(sizeof(Node));
if(!pnode)
{
printf("initList malloc error.\n");
exit(1);
}
pnode->link = pnode;
*plist = pnode;
return ;
}
int insertList(NodePointer * plist, const Element * e) //尾部插入
{
NodePointer pnode, rear;
pnode = (NodePointer)malloc(sizeof(Node));
if(!pnode)
{
printf("insertList malloc error.\n");
return 0;
}
rear = (*plist);
while(rear->link != *plist)
rear = rear->link;
pnode->elem = *e;
pnode->link = *plist;
rear->link = pnode;
return 1;
}
int deleteList(NodePointer * plist, const Element * e) //根据e删除一个节点
{
NodePointer pnode, prev;
prev = (*plist);
pnode = (*plist)->link;
while(pnode != *plist)
{
if(memcmp(&(pnode->elem), e, sizeof(Element)) == 0)
{
prev->link = pnode->link;
free(pnode);
return 1;
}
prev = pnode;
pnode = pnode->link;
}
return 0;
}
NodePointer invertList(NodePointer list)//反转一个链表
{
NodePointer current, prev;
NodePointer temp;
prev = list;
current = prev->link;
while(current != list)
{
temp = current->link;
current->link = prev;
prev = current;
current = temp;
}
current->link = prev;
return current;
}
void destoryList(NodePointer * plist)
{
NodePointer pnode, temp;
pnode = (*plist)->link;
while(pnode != *plist)
{
temp = pnode;
pnode = pnode->link;
free(temp);
}
free(pnode);
}
void showList(const NodePointer * plist)
{
NodePointer pnode;
int count = 0;
pnode = (*plist)->link;
while(pnode != *plist)
{
printf("%d\t", (pnode->elem).data);
pnode = pnode->link;
if(count++ % 5 == 4)
printf("\n");
}
}
从上面的插入节点函数可以看出其效率非常低, 因为每次插入节点都需要遍历一遍整个链表,查找到尾节点。
解决办法是,不用头节点,使用链表的尾节点指针作为插入函数的参数,这样可以方便的插入到表头表尾。
如 rear,表示尾节点, node 是需要插入的节点
头插: node->link = rear->link; rear->link = node;
尾插:node->link = rear->link; rear->link = node; rear = node;