单向链表
单链表:它通过一系列节点来存储数据元素。
构成:每个节点包含两部分:一部分是数据,另一部分是指向下一个节点的指针。
- 数据域:单链表中的每个节点都包含一个数据域,用于存储数据元素。eg. p->date.
- 指针域:每个节点有一个指针域,该指针指向链表中的下一个节点。最后一个节点的指针通常指向空(NULL),表示链表的结束。eg. p->next
特点:
- 动态分配内存:用malloc函数为链表进行内存的分配
- 顺序访问:访问单链表中的元素必须按照链表的顺序,即从第一个节点开始,沿着指针逐个访问到目标节点。
基本操作: 插入,删除 改变 查找
#include<stdio.h>
#include<malloc.h>
/**
* Linked list of characters.The key is data.
*/
typedef struct LinkNode{
char date;
struct LinkNode *next;
}LNode,*LinkList,*NodePtr;
/**
* Initialize the list with a header.
* @return The pointer to the header.
*/
LinkList iniLinkList(){
NodePtr tempHeader = (NodePtr)malloc(sizeof(LNode));
tempHeader->date ='\0';
tempHeader->next = NULL;
return tempHeader;
}//of intLinkList
/**
* 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 th 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->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 paramPosition 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 paramHeader 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 = iniLinkList();
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.
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 second node: %d,%d,%d\r\n",&tempNode2,&tempNode2.date,&tempNode2.next);
tempNode1.next = &tempNode2;
}//of basicAddressTest
/**
* The entrance.
*/
int main()
{
appendInsertDeleteTest();
}//of main
运行结果
图示: