链表的插入,删除,遍历等功能的实例
工程一共包含4个文件
1. Entity.h :声明表的元素的类型。可以是基本数据类型也可以是结构体
2. ChainList.h :定义表结构体,声明全局的宏定义,函数的声明
3. ChainList.c :具体的函数实现
4. main.c : 测试文件参考博客文章: http://www.cnblogs.com/laojie4321/archive/2012/03/30/2425015.html
参考博客文章: http://blog.163.com/jiaoruijun07@126/blog/static/68943278201042064246409/
Entity.h
typedef struct{
char key[15]; //结点的关键字
char name[20];
int age;
} DATA; //定义结点类型 可定义为简单类型或者结构体
ChainList.h
/*
头文件:数据结构的定义和操作原型
*/
#include <stdio.h>
#include "Entity.h"
typedef struct Node{
DATA data; //数据域
struct Node *next; //指针域,指向下一个结点的地址
} ChainListType;
ChainListType *ChainListAddEnd(ChainListType *head, DATA data); //添加结点到链表结尾
ChainListType *ChainListAddFirst(ChainListType *head, DATA data); //添加结点到头部
ChainListType *ChainListInsert(ChainListType *head, char *findKey, DATA data);//把数据插入链表(插入到某个关键字之后)
ChainListType *ChainListFind(ChainListType *head, char *key); //按关键字查找
int ChainListDelete(ChainListType *head, char *key); //删除指定关键字的结点
int ChainListLength(ChainListType *head); //获取链表结点数量
ChainList.c
#include <string.h>
#include <malloc.h>
#include "ChainList.h"
/*添加结点到链表结尾*/
ChainListType *ChainListAddEnd(ChainListType *head, DATA data){
ChainListType *node, *h; //临时变量 用于保存新结点的地址和链表当前(头结点和循环时候的)结点的地址(即head)
if(! (node = (ChainListType *)malloc(sizeof(ChainListType)))){//申请赋予内存地址用来保存新结点
//如果失败
printf("申请内存失败\n");
return NULL;
}
//分配成功
node->data = data; //设置数据域
node->next = NULL; //设置指针域指向空(这是一个结点)
//把新加的结点连接到链表
if(head == NULL){ //如果头结点为空 表示没有实际结点
head = node; //头结点指向这个新结点
printf("|||||");
ChainListLength(head);
printf("|||||");
return head;
}else{ //头结点不为空 遍历到达当前链表的最后一个结点
h = head;
while(h->next != NULL){
h = h->next;
}
h->next = node;//到达最后一个结点 赋值
return head;
}
}
/*添加结点到头部*/
ChainListType *ChainListAddFirst(ChainListType *head, DATA data){
ChainListType *node; //临时变量 用于保存新结点的地址和链表当前(头结点和循环时候的)结点的地址(即head)
if(! (node = (ChainListType *)malloc(sizeof(ChainListType)))){//申请赋予内存地址用来保存新结点
//如果失败
printf("申请内存失败\n");
return NULL;
}
//分配成功
node->data = data; //设置数据域
node->next = head; //设置指针域指向原来头指针指向的地址
head = node; //头结点指向新增结点
return head;
}
/*把数据插入链表(插入到某个关键字之后)*/
ChainListType *ChainListInsert(ChainListType *head, char *findKey, DATA data){
ChainListType *node, *node1; //临时变量 用于保存新结点的地址
if(! (node = (ChainListType *)malloc(sizeof(ChainListType)))){//申请赋予内存地址用来保存新结点
//如果失败
printf("申请内存失败\n");
return NULL;
}
//分配成功
node->data = data; //设置数据域
node1 = ChainListFind(head, findKey); //查找指定关键字的结点
if(node1){ //如果找到该结点
node->next = node1->next; //把找到的结点的下一个结点的地址赋值给新结点
node1->next = node; //把找到的结点的指针域指向新结点
}else{
free(node); //释放内存
printf("没有找到结点");
}
return head;
}
/*按关键字查找*/
ChainListType *ChainListFind(ChainListType *head, char *key){
ChainListType *h;
h = head;
while(h){
if(strcmp(h->data.key, key) == 0){ //字符串对比函数 相同则返回0
return h;
}
h = h->next;
}
return NULL;
}
/*删除指定关键字的结点*/
int ChainListDelete(ChainListType *head, char *key){
ChainListType *node, *h; //h指向循环当前结点 node指向h的前一个结点
node = h = head;
while(h){
if(strcmp(h->data.key, key) == 0){ //字符串对比函数 相同则返回0
node->next = h->next;
free(h); //释放 删除
return 1;
}else{
node = h; //把h赋值给node
h = h->next; //h指向h的下一个结点
}
}
return 0;
}
/*获取链表结点数量*/
int ChainListLength(ChainListType *head){
ChainListType *h;
int i = 0;
h = head;
if(h == NULL){
printf("没有数据!!!");
return 0;
}
while(h){
h = h->next;
i++;
}
return i;
}
main.c
/* 测试文件:调用测试函数*/
#include <stdio.h>
#include "ChainList.h"
/*遍历链表的数据*/
void ChainListAll(ChainListType *head){
ChainListType *h;
h = head;
printf("链表所有的数据:\n");
while(h){ //判断当前结点的存在
printf("%s %s %d \t", h->data.key, h->data.name, h->data.age);
h = h->next;
}
return;
}
int main(void){
ChainListType *node, *head = NULL;
DATA data;
int k, i;
char key[15];
while(1){
fflush(stdin);
printf("\n\n输入操作\n1.插入到末尾\t2.内容查询\t3.插入到头部\t4.插入到指定结点之后\t5.删除\t6.求长度\t7.遍历\t8.退出\n:");
scanf("%d", &k);
if(k == 8){
break;
}
switch(k){
case 1:
printf("插入到末尾:输入元素内容:");
scanf("%s %s %d", &data.key, &data.name, &data.age);
head = ChainListAddEnd(head, data);
printf("插入的元素为:(%s %s %d) \n", head->data.key, head->data.name, head->data.age);
break;
case 2:
printf("输入元素key:");
scanf("%s", &key);
node = ChainListFind(head, &key);
printf("元素为:(%s %s %d) \n", node->data.key, node->data.name, node->data.age);
break;
case 3:
printf("插入到头部:输入元素内容:");
scanf("%s %s %d", &data.key, &data.name, &data.age);
head = ChainListAddFirst(head, data);
printf("插入的元素为:(%s %s %d) \n", head->data.key, head->data.name, head->data.age);
break;
case 4:
printf("插入到指定结点之后:输入位置元素key和元素内容:");
scanf("%s %s %s %d", &key, &data.key, &data.name, &data.age);
head = ChainListInsert(head, &key, data);
printf("插入的元素为:(%s %s %d) \n", head->data.key, head->data.name, head->data.age);
break;
case 5:
printf("输入要删除的元素key:");
scanf("%s", &key);
i = ChainListDelete(head, &key);
if(i == 1){
printf("删除成功\n");
}else{
printf("删除失败\n");
}
break;
case 6:
printf("-----%d------\n", ChainListLength(head));
break;
case 7:
ChainListAll(head);
break;
}
}
return 0;
}
个人博客 欢迎来访: http://ay2626.me