这个实现可能有许多的错误, 还有最后最数据结构最后的测试上, 费了不少力, 请大家看完后不吝赐教!!!
贴代码啦
LinkList.h
#ifndef _SINGLELINKLIST_H #define _SINGLELINKLIST_H /*这是一种简单的链表的实现方式*/ //typedef int Elemtype; struct node; /*刚开始这个地方写成了typedef struct *PtrToNode;最后导致无法编译*/ typedef struct node *PtrToNode; /*在结构体后面没有定义指针,而是使用了如下的定义 ,在编译时出现left of 'next' specifies undefined struct/union '$S1'*/ typedef PtrToNode List; typedef PtrToNode Position; typedef struct{ char key[15]; char name[20]; int age; }Elemtype; typedef struct node { Elemtype elem; struct node * next; };//*Position,*List; /* 初始化头结点*/ /* 第一种初始化方式*/ //List InitList(List L); /* 第二种初始化方式*/ void InitList(List *L); /* 是不是空表*/ int IsEmpty(List L); /* 判断是不是最后一个元素*/ int IsLast(List L, Position P); /* 插入元素,倒插法,新插入的元素为表的第一个元素*/ void AddFirst(List L, Elemtype elem); /* 插入元素,插入元素到表尾*/ void AddEnd(List L, Elemtype elem); /* 返回特定的数据在表中位置*/ Position Find(List L, char *key); /* 如果key找到, 则返回key对应的前一个节点*/ Position FindPrevious(List L, char *key); /* 在特定结点的后面插入新的结点*/ int Insert(List L, Elemtype elem, char *key); /* 删除表中某个特定元素*/ int Delete(List L, char *key); /* 销毁表*/ void DeleteList(List L); /*获取链表的长度*/ int Length(List L); /*遍历*/ void traverse(List L); #endif /*_SINGLELINKLIST_H*/
LinkList.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "LinkList.h" // /* 1. 第一种初始化写法::不要这么写;*/ // /* 2. 因为表头是亚节点,所以初始化需要分配空间*/ // /* 3. 函数的返回值必须是堆变量如果是栈变量,那么在函数返回的时候就会被销毁*/ // List InitList(List L) // { // L=(struct node *)malloc(sizeof(struct node)); // L->next=NULL; // return L; // /*哑节点如果这样初始化就会出现NullPointException,当然这样的错误vc不会提示*/ // //L = NULL; // } /* 0. 第二种写法*/ /* 1. 刚开始由于不懂运算优先级将*L->next=NULL,->的优先级高于*,并且最后导致编译失败*/ void InitList(List *L) { *L=(List)malloc(sizeof(struct node)); (*L)->next=NULL; } /* 空表返回T, 反之放回F*/ int IsEmpty(List L) { return L->next == NULL; } /* 判断是不是最后一个元素*/ int IsLast(List L, Position P) { return P->next == NULL; } /* 插入元素,倒插法,新插入的元素为表的第一个元素*/ void AddFirst(List L, Elemtype elem) { Position tmpcell; if (!(tmpcell = (struct node *)malloc(sizeof(struct node)))) { printf("节点内存分配失败啦 "); return ; } tmpcell->elem = elem; tmpcell->next = L->next; L->next = tmpcell; } /* 插入元素,插入元素到表尾*/ void AddEnd(List L, Elemtype elem) { Position tmpcell,h; /* 分配一个节点内存*/ if (!(tmpcell = (struct node *)malloc(sizeof(struct node)))) { printf("节点内存分配失败啦 "); return ; } tmpcell->elem = elem; tmpcell->next = NULL; /* 如果是空表*/ if (L->next == NULL) { L->next = tmpcell; return; } /* 如果不是空表*/ /* 移动节点指针,让它指向最后一个节点位置*/ h = L->next; while (h != NULL && h->next != NULL) h = h->next; /* 自己犯得错误写法, 注解一下嘿嘿,导致了h是控制空指针*/ /* 刚开始h到这个地方的时候是空指针,所以下面的写法是错误滴,现在修改好了呀*/ h->next = tmpcell; } /* 返回特定的数据在表中位置*/ /* 1. 如果遍历完后,没有发现这个指针,返回的应该是链表的最后一个元素,应该是NULL*/ /* 2. 这个算法实现参考自 数据结构与算法分析:c语言描述*/ Position Find(List L, char *key) { Position p; p = L->next; while (p != NULL && !(strcmp(p->elem.key,key) == 0)) p = p->next; return p; } /* 如果key找到, 则返回key对应的前一个节点*/ Position FindPrevious(List L, char *key) { Position p; p = L; if (L->next->next == NULL) return NULL; while (p->next != NULL && !(strcmp(p->next->elem.key,key) == 0)) p = p->next; return p; } /*在特定结点的后面插入新的结点*/ int Insert(List L, Elemtype elem, char *key) { Position p, tmpcell; if (!(tmpcell = (struct node *)malloc(sizeof(struct node)))) { printf("节点内存分配失败啦 "); return 0; } p = Find(L,key); if (p) { tmpcell->elem = elem; tmpcell->next = p->next; p->next = tmpcell; } else { free(tmpcell); printf("插入节点失败 "); } return 1; } /*删除表中某个特定元素*/ int Delete(List L, char *key) { Position p,tmpcell; p = Find(L,key); if (!IsLast(L,p)) { tmpcell = p->next; p->next = p->next->next; free(tmpcell); } return 1; } /* 销毁表*/ void DeleteList(List L) { Position p,tmpcell; p = L->next; L->next = NULL; while (p->next != NULL) { tmpcell = p->next; free(p); p = tmpcell; } } /*获取链表的长度*/ int Length(List L) { int i = 0; Position p; p = L->next; while (p != NULL) { i++; p = p->next; } return i; } /* 遍历*/ void traverse(List L) { Position p; p = L->next; if (L->next== NULL) return; printf(" 当前单链表中所有的存储的数据为: "); while(p!= NULL) { /*在这个地方第一次写成了L,并导致失败!*/ printf("%s %s %d ",p->elem.key,p->elem.name,p->elem.age); p = p->next; } }
最后测试,也是最破烦的, 由于半路出家, 不太会, 由着自己写啦
#include <stdio.h> #include <string.h> #include "LinkList.h" int main() { Elemtype elem; List L; Position p; char buf[15]; //key int len; /*1. 第一种初始化*/ /*2. 不过这种不建议实用*/ //L = InitList(L); /*拾遗. 1. 如果指针没有初始化,那么L==0xcccccccc*/ /*拾遗. 2. 想要修改或者是保存某个实参变量的值,那么就应该传递指向这个实参变量的指针*/ /*2. 第二种初始化方式*/ InitList(&L); printf("请输入 关键词 姓名 年龄(关键词输入0 ,则退出) "); /*插入一些数据到表中*/ do { printf("请输入关键词 "); fflush(stdin); scanf("%s",elem.key); if (strcmp(elem.key,"0")==0) break; scanf("%s%d",elem.name,&elem.age); //AddFirst(L,elem);//测试通过 AddEnd(L,elem); } while (1); // /* 测试在表头进行插入*/ // fflush(stdin); // scanf("%s",elem.key); // scanf("%s%d",elem.name,&elem.age); // AddFirst(L,elem); // /* 测试查找给定关键词所对应的节点*/ // p = Find(L, "chen"); // if (p) // printf(" %s %s %d",p->elem.key, p->elem.name, p->elem.age); // /* 测试查找给定关键词所对应的前一个节点*/ // p = FindPrevious(L, "chen"); // if (p) // printf(" %s %s %d",p->elem.key, p->elem.name, p->elem.age); // /* 测试插入元素*/ // printf(" 请输入插入的关键词位置啦"); // fflush(stdin); // scanf("%s",buf); // printf(" 请输入插入的元素!!! "); // fflush(stdin); // scanf("%s",elem.key); // scanf("%s%d",elem.name,&elem.age); // Insert(L,elem, buf); // /* 测试表是否为空*/ // if (IsEmpty(L)) // printf(">>>>>>>>>>>>>>>>>>>>>>是空表! "); // else // printf(">>>>>>>>>>>>>>>>>>>>>>表中含有数据! "); // /* 测试删除指定位置的元素*/ // printf(" 请输入删除的关键词位置啦 "); // fflush(stdin); // scanf("%s",buf); // Delete(L,buf); // /* 测试取得链表的长度*/ // len = Length(L); // printf(" %d",len); // traverse(L); // DeleteList(L); traverse(L); free(L); return 0; }