单链表
1.创建一个头结点并初始化
自写的
struct Node
{
int data; //数据域
struct Node *next; //指针域
};
//创建一个头节点注意初始化
struct Node *createList()
{
struct Node *headNode = (struct Node *)malloc(sizeof(struct Node));
headNode->data = '\0';
headNode->next = NULL;
return headNode;
}
老师的
typedef struct LinkNode{
char data;
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->data = '\0';
tempHeader->next = NULL;
return tempHeader;
2.创建结点
自写的
//创建节点
struct Node *creatNode(int data)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
3.打印链表
自写的
//打印链表
void printList(struct Node *headNode)
{
struct Node *pMove = headNode->next;
while (pMove != NULL)
{
printf("%d ", pMove->data);
pMove = pMove->next;
}
printf("\n");
}
老师的
void printList(NodePtr paraHeader){
NodePtr p = paraHeader->next;
while (p != NULL) {
printf("%c", p->data);
p = p->next;
}// Of while
printf("\r\n");
}
4.插入元素
自写的
//头插法连接各个节点
void insertNodeByHead(struct Node *headNode, int data)
{
struct Node *newNode = creatNode(data);
printf("开始从头部连接%d\n", data);
newNode->next = headNode->next;
headNode->next = newNode;
}
//尾插法连接各个节点
void insertNodeByTail(struct Node *headNode, int data)
{
struct Node *newNode = creatNode(data);
struct Node *pMove = headNode;
while (pMove->next != NULL)
{
pMove = pMove->next;
}
printf("开始从尾部连接%d\n", data);
pMove->next = newNode;
}
//在中间连接一个节点
void insertNodeBymiddle(struct Node *headNode, int data, int position)
{
struct Node *newNode = creatNode(data);
struct Node *pMove = headNode;
for (int i = 0; i < position; i++)
{
pMove = pMove->next;
if (pMove == NULL)
{
printf("输入的位置%d超出了链表的最大长不能插入元素。\n", position);
return;
}
}
//实际上是在该位置的后面插入一个节点
printf("开始从中间连接%d\n", data);
newNode->next = pMove->next;
pMove->next = newNode;
}
//在指定值后面插入一个节点
void insertNodeByData(struct Node *headNode, int paraData, int Data)
{
struct Node *newNode = creatNode(Data);
struct Node *pMove = headNode->next;
while (pMove->data != paraData)
{
if (pMove == NULL)
{
printf("未能找到该元素,无法添加。\n");
return;
}
pMove = pMove->next;//特别注意这里尤其考虑该值在最后的时候
//pMove和pMove->next不一样
}
printf("在%d后面添加元素%d\n", paraData, Data);
newNode->next = pMove->next;
pMove->next = newNode;
}
老师的
//w尾插法
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.
//找到1尾部
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->data = paraChar;
// Step 3. Now link.
printf("linking\r\n");
q->next = p->next;
p->next = q;
}// Of insertElement
5.删除元素
自写的
//链表的指定值的删除方法一
void deleteNodeByAppionWayOne(struct Node *headNode, int posData)
{
struct Node *posNode = headNode->next;
struct Node *posNodeFront = headNode;
if (posNode == NULL)
{
printf("链表为空无法删除。\n");
}
else
{
while (posNode->data != posData)
{
posNodeFront = posNode;
posNode = posNodeFront->next;
if (posNode == NULL)
{
printf("没有找到%d的信息,无法删除。\n", posData);
return;
}
}
printf("删除%d\n", posData);
posNodeFront->next = posNode->next;
free(posNode);
}
}
//链表的指定值删除方法二
void deleteNodeByAppionWayTwo(struct Node *headNode, int posData)
{
struct Node *p;
struct Node *q;
p = headNode;
while (p->next != NULL && p->next->data != posData)
{
p = p->next;
}
if (p->next == NULL)
{
printf("没有找到%d的信息,无法删除。\n", posData);
return;
}
printf("删除 %d\n", posData);
q = p->next;
p->next = p->next->next;
free(q);
}
//链表的指定位置删除
void deleteNodeByposition(struct Node *headNode, int position)
{
struct Node *pMove = headNode;
struct Node *q;
if (position <= 0)
{
printf("无效位置 %d。\n", position);
return;
}
for (int i = 1; i < position; i++)
{
pMove = pMove->next;
}
if (pMove->next == NULL)
{
printf("要删除的位置 %d 已经超出链表的最大长度不能删除该位置。\n", position);
return;
}
printf("删除位置 %d 的元素\n", position);
q = pMove->next;
pMove->next = pMove->next->next;
free(q);
}
老师的
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
6.所有代码
自写的
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data; //数据域
struct Node *next; //指针域
};
//创建一个头节点注意初始化
struct Node *createList()
{
struct Node *headNode = (struct Node *)malloc(sizeof(struct Node));
headNode->data = '\0';
headNode->next = NULL;
return headNode;
}
//创建节点
struct Node *creatNode(int data)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
//打印链表
void printList(struct Node *headNode)
{
struct Node *pMove = headNode->next;
while (pMove != NULL)
{
printf("%d ", pMove->data);
pMove = pMove->next;
}
printf("\n");
}
//头插法连接各个节点
void insertNodeByHead(struct Node *headNode, int data)
{
struct Node *newNode = creatNode(data);
printf("开始从头部连接%d\n", data);
newNode->next = headNode->next;
headNode->next = newNode;
}
//尾插法连接各个节点
void insertNodeByTail(struct Node *headNode, int data)
{
struct Node *newNode = creatNode(data);
struct Node *pMove = headNode;
while (pMove->next != NULL)
{
pMove = pMove->next;
}
printf("开始从尾部连接%d\n", data);
pMove->next = newNode;
}
//在中间连接一个节点
void insertNodeBymiddle(struct Node *headNode, int data, int position)
{
struct Node *newNode = creatNode(data);
struct Node *pMove = headNode;
for (int i = 0; i < position; i++)
{
pMove = pMove->next;
if (pMove == NULL)
{
printf("输入的位置%d超出了链表的最大长不能插入元素。\n", position);
return;
}
}
//实际上是在该位置的后面插入一个节点
printf("开始从中间连接%d\n", data);
newNode->next = pMove->next;
pMove->next = newNode;
}
//在指定值后面插入一个节点
void insertNodeByData(struct Node *headNode, int paraData, int Data)
{
struct Node *newNode = creatNode(Data);
struct Node *pMove = headNode->next;
while (pMove->data != paraData)
{
pMove = pMove->next;
if (pMove == NULL)
{
printf("未能找到该元素,无法添加。\n");
return;
}
}
printf("在%d后面添加元素%d\n", paraData, Data);
newNode->next = pMove->next;
pMove->next = newNode;
}
//链表的指定值的删除方法一
void deleteNodeByAppionWayOne(struct Node *headNode, int posData)
{
struct Node *posNode = headNode->next;
struct Node *posNodeFront = headNode;
if (posNode == NULL)
{
printf("链表为空无法删除。\n");
}
else
{
while (posNode->data != posData)
{
posNodeFront = posNode;
posNode = posNodeFront->next;
if (posNode == NULL)
{
printf("没有找到%d的信息,无法删除。\n", posData);
return;
}
}
printf("删除%d\n", posData);
posNodeFront->next = posNode->next;
free(posNode);
}
}
//链表的指定值删除方法二
void deleteNodeByAppionWayTwo(struct Node *headNode, int posData)
{
struct Node *p;
struct Node *q;
p = headNode;
while (p->next != NULL && p->next->data != posData)
{
p = p->next;
}
if (p->next == NULL)
{
printf("没有找到%d的信息,无法删除。\n", posData);
return;
}
printf("删除 %d\n", posData);
q = p->next;
p->next = p->next->next;
free(q);
}
//链表的指定位置删除
void deleteNodeByposition(struct Node *headNode, int position)
{
struct Node *pMove = headNode;
struct Node *q;
if (position <= 0)
{
printf("无效位置 %d。\n", position);
return;
}
for (int i = 1; i < position; i++)
{
pMove = pMove->next;
}
if (pMove->next == NULL)
{
printf("要删除的位置 %d 已经超出链表的最大长度不能删除该位置。\n", position);
return;
}
printf("删除位置 %d 的元素\n", position);
q = pMove->next;
pMove->next = pMove->next->next;
free(q);
}
void allTest()
{
//创建一个链表
struct Node *List = createList();
insertNodeByHead(List, 1);
insertNodeByHead(List, 2);
insertNodeByHead(List, 3);
insertNodeByHead(List, 4);
printList(List);
//测试根据元素值删除方法一
deleteNodeByAppionWayOne(List, 2);
printList(List);
deleteNodeByAppionWayOne(List, 7);
printList(List);
//测试尾插法
insertNodeByTail(List, 10);
printList(List);
//测试中间插入元素
insertNodeBymiddle(List, 20, 2);
printList(List);
insertNodeBymiddle(List, 11, 10);
printList(List);
//测试根据元素值删除方式二
deleteNodeByAppionWayTwo(List, 10);
printList(List);
deleteNodeByAppionWayTwo(List, 2);
printList(List);
// 测试根据位置删除
deleteNodeByposition(List, 0);
printList(List);
deleteNodeByposition(List, 1);
printList(List);
//测试指定值后面插入元素
insertNodeByData(List, 20, 23);
printList(List);
}
int main()
{
allTest();
}
老师的`
#include <stdio.h>
#include <malloc.h>
/**
* Linked list of characters. The key is data.
*/
typedef struct LinkNode{
char data;
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->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 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->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.
insertElement(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();
basicAddressTest();
}// Of main
7.测试结果
自写的
开始从头部连接1
开始从头部连接2
开始从头部连接3
开始从头部连接4
4 3 2 1
删除2
4 3 1
没有找到7的信息,无法删除。
4 3 1
开始从尾部连接10
4 3 1 10
开始从中间连接20
4 3 20 1 10
输入的位置10超出了链表的最大长不能插入元素。
4 3 20 1 10
删除 10
4 3 20 1
没有找到2的信息,无法删除。
4 3 20 1
无效位置 0。
4 3 20 1
删除位置 1 的元素
3 20 1
在20后面添加元素23
3 20 23 1
老师的
Hello!
Cannot delete a
Hll!
linking
Holl!
The first node: 6421984, 6421984, 6421992
The second node: 6421968, 6421968, 6421976