顺序表的插入删除操作需要移动大量的元素,影响程序的运行效率,因此引入线性的链式存储单链表。
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
单链表的特点:单链表不要求逻辑上相邻的两个元素在物理位置上也相邻,因此不需要连续的存储空间。
代码抄写如下:
#include <stdio.h>
#include <malloc.h>
/**
*Linked list of characters. The key is date.
*/
typedef struct LinkNode{
char date;
struct LinkNode *next;
} Lnode, *LinkList, *NodePtr;
/**
*Initialize the list with a header.
*@return the pointer to the header.
*/
LinkList initLinkList(){
NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode));
tempHeader->date = '\0';
tempHeader->next = NULL;
return tempHeader;
}// of initLinkList
/**
*print the list.
*param paraHeader the header of the list.
*/
void printList(NodePtr paraHeader){
Nodeptr p = paraHeader->next;
while(p != NULL){
printf("%c" , p->date);
p = p->next;
}// of while
printf("\r\n");
}// of printList
/**
*Add an element to the tail.
*@param paraHeader the header of the list.
*@param paraChar the giver char.
*/
void appendElement(NodePtr paraHeader , char paraChar){
NodePtr p,q;
//step 1. Construct a new node.
q = (NodePtr)malloc(sizeof(LNode));
q->date = paraChar;
q->next = NULL;
//step 2.Search to the tail.
p = paraHeader;
while(p->next != NULL){
p = p->next;
}// of while
//step 3. Now add/link
p->next = q;
}// of appendElement
/**
*Insert an element to the given position.
*@param paraHeader the header of the list.
*@param paraChar the given char.
*@param paraPosition the given position.
*/
void insertElement(NodePtr paraHeader , char paraChar , int paraPosition){
NodePtr p,q;
//step 1.Search to the position.
p = paraHeader;
for (int i = 0; i < paraPosition; i ++){
p = p->next;
if(p == NULL){
printf("the position %d is beyond the scope of the list.",paraPosition);
return;
}//of if
}// of for i
//step 2. Construct a new node.
q = (NodePtr)malloc(sizeof(LNode));
q->date = paraChar;
//step 3.Now link
printf("linking\r\n");
q->next = p->next;
p->next = q;
}// of insertElement
/**
*Delete an element from the list.
*@param paraHeader the header of the list.
*@param paraChar the given char.
*/
void deleteElement(NodePtr paraHeader , char paraChar){
NodePtr p , q;
p = paraHeader;
while((p->next != NULL)&&(p->next->date != paraChar)){
p = p->next;
}// of while
if(p->next == NULL){
printf("cannot delete %c\r\n" , paraChar);
return;
}// of if
q = p->next;
p->next = p->next->next;
free(q);
}// of deleteElement
/**
*Unit test
*/
void appendInsertDeleteTest(){
//step 1.initialize an empty list;
LinkList tempList= initLinkList();
printList(tempList);
//step 2.Add somecharacters.
appendElement(tempList,'H');
appendElement(tempList,'e');
appendElement(tempList,'l');
appendElement(tempList,'l');
appendElement(tempList,'o');
appendElement(tempList,'!');
printList(tempList);
//step 3.Delete some characters.(the first occurrence).
deleteElement(tempList,'e');
deleteElement(tempList,'a');
deleteElement(tempList,'o');
printList(tempList);
//step 4.insert to a given position.
insertElement(tempList,'o',1);
printList(tempList);
}// of appendInsertDeleteTest
/**
*Address test: beyond the book.
*/
void basicAddressTest(){
LNode tempNode1,tempNode2;
tempNode1.date = 4;
tempNode1.next = NULL;
tempNode2.date = 6;
tempNode2.next = NULL;
printf("The first Node: %d, %d, %d\r\n", &tempNode1, &tempNode1.date, &tempNode1.next);
printf("The scond Node: %d, %d, %d\n\r", &tempNode2, &tempNode2.date, &tempNode2.next);
tempNode1.next = &tempNode2;
}// of basicAddressTest
/**
*The entrance.
*/
int main(){
appendInsertDeleteTest();
}// of main.
运行结果如下:
总结:单链表因为使用指针来储存下一个节点的位置,从而大大减少了不必要的内存开销。但是由于链表不具备通过下标进行访问的能力,如果要访问后面的元素需要访问前面的所有元素 ,大大增加了时间的损耗。