#include <stdio.h>
#include <malloc.h>
/**
*Linked list of chararters,thekey is date.
*/
typedef struct LinkNode{
char data;
struct LinkNode *next;
}LNode,*LinkList,*NodePtr;
/**
* @return The pointer to the header.
*/
LinkList initLinkList(){
NodePtr tempHeader=(NodePtr)malloc(sizeof(LNode));
tempHeader->data= '\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->data);
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 given char.
*/
void appendElement(NodePtr paraHeader,char paraChar){
NodePtr p, q;
// Step 1. Construct a new node.
q= (NodePtr)malloc(sizeof(LNode));
q->data= 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 inserElement(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->data= 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->data!= 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 some characters.
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.
inserElement(tempList, 'o',1);
printList(tempList);
}// Of appendInsertDeleteTest
/**
* Address test: beyond the book.
*/
void basicAddressTest(){
LNode tempNode1, tempNode2;
tempNode1.data= 4;
tempNode1.next= NULL;
tempNode2.data= 6;
tempNode2.next= NULL;
printf("The first node: %d, %d, %d\r\n",
&tempNode1, &tempNode1.data, &tempNode1.next);
printf("The second node: %d, %d, %d\r\n",
&tempNode2, &tempNode2.data, &tempNode2.next);
tempNode1.next= &tempNode2;
}// Of basicAddressTest
/**
* The entrance.
*/
int main(){
appendInsertDeleteTest();
}// Of main
运行结果如下:
学习体会:
单链表的定义
由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。
单链表的特点:
单链表不要求逻辑上相邻的两个元素在物理位置上也相邻,因此不需要连续的存储空间。
单链表是非随机的存储结构,即不能直接找到表中某个特定的结点。查找某个特定的结点时,需要从表头开始遍历,依次查找
头插法建立单链表
所谓头插法建立单链表是说将新结点插入到当前链表的表头,即头结点之后。算法思想:首先初始化一个单链表,其头结点为空,然后循环插入新结点*s:将s的next指向头 结点的下一个结点,然后将头结点的next指向s。
尾插法建立单链表
所谓尾插法建立单链表,就是将新结点插入到当前链表的表尾。算法思想:首先初始化一个单链表,然后声明一个尾指针r,让r始终指向当前链表的尾结点,循环向单链表的尾部插入新的结点*s,将尾指针r的next域指向新结点,再修改尾指针r指向新结点,也就是当前链表的尾结点。最后别忘记将尾结点的指针域置空。