首先是双向链表
1.创建
typedef struct DoubleLinkedNode{
char data;
struct DoubleLinkedNode *previous;
struct DoubleLinkedNode *next;
} DLNode, *DLNodePtr;
2.初始化
DLNodePtr initLinkList(){
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(DLNode));
tempHeader->data = '\0';
tempHeader->next = NULL;
tempHeader->previous = NULL;
return tempHeader;
}
3.插入
void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
DLNodePtr p, q, r;
p = paraHeader;
int i;
for (i = 0; i < paraPosition; i ++) {
p = p->next;
if (p == NULL) {
printf("The position %d is beyond the scope of the list.", paraPosition);
return;
}
}
q = (DLNodePtr)malloc(sizeof(DLNode));
q->data = paraChar;
r = p->next;
q->next = r;
q->previous = p;
p->next = q;
if (r != NULL) {
r->previous = q;
}
}
4.删除
void deleteElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p, q, r;
p = paraHeader;
while ((p->next != NULL) && (p->next->data != paraChar)){
p = p->next;
}
if (p->next == NULL) {
printf("The char '%c' doer not exist.\n", paraChar);
return;
}
q = p->next;
r = q->next;
p->next = r;
if (r != NULL) {
r->previous = p;
}
free(q);
}
5.查找
DLNodePtr locateElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p = paraHeader;
while ((p->next != NULL) && (p->next->data != paraChar)) {
p = p->next;
}
if (p->next == NULL) {
printf("The char '%c' does not exist\n", paraChar);
return;
}
return p;
}
6.总代码
#include<stdio.h>
#include<stdlib.h>
typedef struct DoubleLinkedNode{
char data;
struct DoubleLinkedNode *previous;
struct DoubleLinkedNode *next;
} DLNode, *DLNodePtr;
/**
*创建头结点
*/
DLNodePtr initLinkList(){
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(DLNode));
tempHeader->data = '\0';
tempHeader->next = NULL;
tempHeader->previous = NULL;
return tempHeader;
}
/**
*输出
*/
void printList(DLNodePtr paraHeader){
DLNodePtr p = paraHeader->next;
while (p != NULL) {
printf("%c", p->data);
p = p->next;
}
printf("\n");
}
/**
*插入元素
*/
void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
DLNodePtr p, q, r;
p = paraHeader;
int i;
for (i = 0; i < paraPosition; i ++) {
p = p->next;
if (p == NULL) {
printf("The position %d is beyond the scope of the list.", paraPosition);
return;
}
}
q = (DLNodePtr)malloc(sizeof(DLNode));
q->data = paraChar;
r = p->next;
q->next = r;
q->previous = p;
p->next = q;
if (r != NULL) {
r->previous = q;
}
}
/**
*删除
*/
void deleteElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p, q, r;
p = paraHeader;
while ((p->next != NULL) && (p->next->data != paraChar)){
p = p->next;
}
if (p->next == NULL) {
printf("The char '%c' doer not exist.\n", paraChar);
return;
}
q = p->next;
r = q->next;
p->next = r;
if (r != NULL) {
r->previous = p;
}
free(q);
}
/**
*查找
*/
DLNodePtr locateElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p = paraHeader;
while ((p->next != NULL) && (p->next->data != paraChar)) {
p = p->next;
}
if (p->next == NULL) {
printf("The char '%c' does not exist\n", paraChar);
return NULL;
}
return p;
}
/**
*测试
*/
void insertDeleteTest(){
DLNodePtr tempList = initLinkList();
printList(tempList);
insertElement(tempList, 'H', 0);
insertElement(tempList, 'e', 1);
insertElement(tempList, 'l', 2);
insertElement(tempList, 'l', 3);
insertElement(tempList, 'o', 4);
insertElement(tempList, '!', 5);
printList(tempList);
deleteElement(tempList, 'e');
deleteElement(tempList, 'a');
deleteElement(tempList, 'o');
printList(tempList);
insertElement(tempList, 'o', 1);
printList(tempList);
}
void basicAddressTest(){
DLNode tempNode1, tempNode2;
tempNode1.data = 4;
tempNode1.next = NULL;
tempNode2.data = 6;
tempNode2.next = NULL;
printf("The first node: %p, %p, %p\n", &tempNode1, &tempNode1.data, &tempNode1.next);
printf("The second node: %p, %p, %p\n", &tempNode2, &tempNode2.data, &tempNode2.next);
}
void locateElementTest(){
DLNodePtr tempList = initLinkList();
insertElement(tempList, 'H', 0);
insertElement(tempList, 'e', 1);
insertElement(tempList, 'l', 2);
insertElement(tempList, 'l', 3);
insertElement(tempList, 'o', 4);
insertElement(tempList, '!', 5);
printList(tempList);
DLNodePtr newList = locateElement(tempList, 'e');
if (newList != NULL) {
printList(newList);
}
newList = locateElement(tempList, 'a');
if (newList != NULL) {
printList(newList);
}
newList = locateElement(tempList, 'o');
if (newList != NULL) {
printList(newList);
}
}
int main(){
insertDeleteTest();
basicAddressTest();
locateElementTest();
return 0;
}
运行结果
静态链表
1.创建
typedef struct StaticLinkedNode{
char data;
int next;
} *NodePtr;
typedef struct StaticLinkedList{
NodePtr nodes;
int* used;
} *ListPtr;
2.带头
结点的链表
ListPtr initLinkedList(){
ListPtr tempPtr = (ListPtr)malloc(sizeof(struct StaticLinkedList));
tempPtr->nodes = (NodePtr)malloc(sizeof(struct StaticLinkedNode) * DEFAUL_SIZE);
tempPtr->used = (int*)malloc(sizeof(int) * DEFAUL_SIZE);
tempPtr->nodes[0].data = '\0';
tempPtr->nodes[0].next = -1;
tempPtr->used[0] = 1;
int i;
for (i = 1; i < DEFAUL_SIZE; i ++){
tempPtr->used[i] = 0;
}
return tempPtr;
}
3.输出
void printList(ListPtr paraListPtr){
int p=0;
while (p != -1) {
printf("%c", paraListPtr->nodes[p].data);
p = paraListPtr->nodes[p].next;
}
printf("\n");
}
4.插入
void insertElement(ListPtr paraListPtr, char paraChar, int paraPosition){
int p, q, i;
p = 0;
for (i = 0; i < paraPosition; i ++){
p = paraListPtr->nodes[p].next;
if (p == -1) {
printf("The position %d is beyond the scope of the list.\n", paraPosition);
return;
}
}
for (i = 1; i < DEFAUL_SIZE; i ++){
if (paraListPtr->used[i] == 0){
printf("Space at %d allocated.\n", i);
paraListPtr->used[i] = 1;
q = i;
break;
}
}
if (i == DEFAUL_SIZE){
printf("No space.\n");
return;
}
paraListPtr->nodes[q].data = paraChar;
printf("linking\n");
paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = q;
}
5.删除
void deleteElement(ListPtr paraListPtr, char paraChar){
int p, q;
p = 0;
while ((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data != paraChar)){
p = paraListPtr->nodes[p].next;
}
if (paraListPtr->nodes[p].next == -1) {
printf("Cannot delete %c\n", paraChar);
return;
}
q = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
paraListPtr->used[q] = 0;
}
总代码
#include<stdio.h>
#include<stdlib.h>
#define DEFAUL_SIZE 5
typedef struct StaticLinkedNode{
char data;
int next;
} *NodePtr;
typedef struct StaticLinkedList{
NodePtr nodes;
int* used;
} *ListPtr;
/**
*带头结点的链表
*/
ListPtr initLinkedList(){
ListPtr tempPtr = (ListPtr)malloc(sizeof(struct StaticLinkedList));
tempPtr->nodes = (NodePtr)malloc(sizeof(struct StaticLinkedNode) * DEFAUL_SIZE);
tempPtr->used = (int*)malloc(sizeof(int) * DEFAUL_SIZE);
tempPtr->nodes[0].data = '\0';
tempPtr->nodes[0].next = -1;
tempPtr->used[0] = 1;
int i;
for (i = 1; i < DEFAUL_SIZE; i ++){
tempPtr->used[i] = 0;
}
return tempPtr;
}
/**
*输出
*/
void printList(ListPtr paraListPtr){
int p=0;
while (p != -1) {
printf("%c", paraListPtr->nodes[p].data);
p = paraListPtr->nodes[p].next;
}
printf("\n");
}
/**
*插入
*/
void insertElement(ListPtr paraListPtr, char paraChar, int paraPosition){
int p, q, i;
p = 0;
for (i = 0; i < paraPosition; i ++){
p = paraListPtr->nodes[p].next;
if (p == -1) {
printf("The position %d is beyond the scope of the list.\n", paraPosition);
return;
}
}
for (i = 1; i < DEFAUL_SIZE; i ++){
if (paraListPtr->used[i] == 0){
printf("Space at %d allocated.\n", i);
paraListPtr->used[i] = 1;
q = i;
break;
}
}
if (i == DEFAUL_SIZE){
printf("No space.\n");
return;
}
paraListPtr->nodes[q].data = paraChar;
printf("linking\n");
paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = q;
}
/**
*删除
*/
void deleteElement(ListPtr paraListPtr, char paraChar){
int p, q;
p = 0;
while ((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data != paraChar)){
p = paraListPtr->nodes[p].next;
}
if (paraListPtr->nodes[p].next == -1) {
printf("Cannot delete %c\n", paraChar);
return;
}
q = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
paraListPtr->used[q] = 0;
}
/**
*测试
*/
void appendInsertDeleteTest(){
ListPtr tempList = initLinkedList();
printList(tempList);
insertElement(tempList, 'H', 0);
insertElement(tempList, 'e', 1);
insertElement(tempList, 'l', 2);
insertElement(tempList, 'l', 3);
insertElement(tempList, 'o', 4);
printList(tempList);
printf("Deleting 'e'.\n");
deleteElement(tempList, 'e');
printf("Deleting 'a'.\n");
deleteElement(tempList, 'a');
printf("Deleting 'o'.\n");
deleteElement(tempList, 'o');
printList(tempList);
insertElement(tempList, 'x', 1);
printList(tempList);
}
int main(){
appendInsertDeleteTest();
return 0;
}
运行结果
总结
1.双向链表使用时,部分操作和单链表一致,差异处在于插入和删除,注意前驱和后继需要改变
2.静态链表用数组的序号来表示内存中的地址,可以直观的看到储存,插入和删除的思路和单链表是一致的,只是在操作上还要将存储空间(也就是used数组)的值修改
3.在测试locateElement函数时,出现了一个问题,那就是在输出的时候,没有考虑到NULL的情况,导致如果有一个查找返回的是NULL,那么之后的查找就不能运行,所以我在打印的时候加了一个判断条件就可以了