02142数据结构导论 第二章线表的链表结构

书上的代码有些不能在编译器上面通过,会导致编译错误,我使用的编译器的是DEV C++编译器,
这个是头文件

在这里插入代码片
```typedef struct{
	int age;
	char name,sex,address;
}DATA;
typedef struct{
	DATA *data;
	int length;
}LinearList;
typedef struct node{
	DATA data;
	struct node *next;
}LinkedList;
typedef struct Node{
	DATA data;
	struct Node *next,*prior;
}DLinkedList; 
这里是链表的操作封装代码:

```c
在这里插入代码片
```#include<stdio.h>
#include<stdlib.h>
#include"LinearTable.h"
LinkedList *InitLinkedList();
int GetLength(LinkedList *list);
LinkedList *GetLinkedList(LinkedList *list,int i);
int GetLocation(LinkedList *list,DATA data);
void DeleteLinkedList(LinkedList *list,DATA data);
void InsertLinkedList(LinkedList *list,int i);
void DeleteRepeat(LinkedList *list);
int main(void) {
	return 0;
}
//初始化链表
//新建一个链表指针,并指向头结点,头节点由malloc()函数动态生成
//将指向头节点的下一个指针位置置空
LinkedList *InitLinkedList() {
	LinkedList *list=(LinkedList*)malloc(sizeof(LinkedList));
	list->next=NULL;
	return list;
}
//获取链表长度
//定义一个工作指针,指向链表的头节点
//如果头节点不为空,则将头节点的一下个地址赋值给工作指针,并将计数器自增
int GetLength(LinkedList *list) {
	LinkedList* workPointer=list;
	int length=0;
	while(workPointer->next!=NULL) {
		length++;
		workPointer=workPointer->next;
	}
	return length+1;
}
//根据指定位置读取链表元素
//定义一个工作指针,指向链表的头节点,一个计数器
//如果计数器小于指定的位置且工作指针的地址不为空不,就将计数器自增,工作指针自动指向下一个结点
//如果计数器等于指定位置,就返回工作指针,否则没有找到
LinkedList *GetLinkedList(LinkedList *list,int i) {
	LinkedList *workPointer=list->next;
	int count=1;
	while(count<i&&workPointer!=NULL) {
		workPointer=workPointer->next;
		count++;
	}
	if(count==i) return workPointer;
	else return NULL;
}
//根据给出的数据类型在链表中查找该元素的位置
//建立一个工作指针,指向头节点,比较头节点所指的首结点数据元素,不相等,就将工作指针自动指向下一个结点
//如果指向的地址不为空,就返回该地址的位置,否则返回 0
int GetLocation(LinkedList *list,DATA data) {
	int location=1;
	LinkedList *workPointer=list->next;
	while((list->next)->data.age!=data.age&&(list->next)->data.name!=data.name&&(list->next)->data.address!=data.address&&(list->next)->data.sex!=data.sex) {
		workPointer=workPointer->next;
		location++;
	}
	if(workPointer!=NULL) return location;
	else return 0;
}
//根据指定位置插入相应的数据元素
//定义一个工作指针,临时指针(用来保存动态生成的结点地址)
//判断,如果插入位置为1,就直接将工作指针指向头节点,否则,将指针指向i的上一个结点,并将节点的数据域赋值
//将工作指针指向结点的地址域赋值给临时指针的地址域,再将临时指针赋值给工作指针指向结点的地址域
void InsertLinkedList(LinkedList *list,int i,DATA data) {
	LinkedList *workPointer,*temp;
	if(i==1) workPointer=list;
	else workPointer=GetLinkedList(list,i-1);
	if(workPointer==NULL) printf("not find");
	else {
		temp=(LinkedList*)malloc(sizeof(LinkedList));
		temp->data=data;
		temp->next=workPointer->next;
		workPointer->next=temp;
	}
}
//根据指定位置删除节点,定义一个工作指针,临时指针(指向待删除的结点)
//判断删除位置,如果i==1就将工作指针指向头节点,临时指针指向首节点,否则将工作指针指向i的上一个结点,临时指针指向待删除结点
//如果工作指针指向地址不为空,且指向地的下一个地址不为空 ;将临时指针的地址域赋值给工作指针的下一个地址域,并释放临时指针
void DeleteLinkedList(LinkedList *list,int i) {
	LinkedList *workPointer,*temp;
	if(i==1) {
		workPointer=list;
		temp=list->next;
	} else {
		workPointer=GetLinkedList(list,i-1);
		temp=GetLinkedList(list,i);
	}
	if(workPointer!=NULL&&workPointer->next!=NULL) {
		workPointer->next=temp->next;
		free(temp);
	} else {
		printf("not find this data");
	}
}
//删除重复结点:
//总共定义三个指针:
//第一个指针指向链表的首节点,第二个指针指向第一个指针的下一个结点,第三个指针为临时指针保存第二个指针
//外层: 第一个指针指向链表的首节点,当指针不为空时,
// 内层:将第一个指针和第二个指针的数据域进行比较,如果相等,就创建临时指针变量保存第二指针,将第二指针的地址域指向临时指针的下一个地址域
//      释放临时指针 ,同时将工作指针向后移动
//将指针移动到下一个链表结点
void DeleteRepeat(LinkedList *list) {
	LinkedList *workOuterPointer=list->next,*workInnerPointer=workOuterPointer->next;
	while(workOuterPointer!=NULL) {
		while(workInnerPointer!=NULL) {
			if(workOuterPointer->data.age==workInnerPointer->data.age&&workOuterPointer->data.name==workInnerPointer->data.name&&
			        workOuterPointer->data.sex==workInnerPointer->data.sex&&workOuterPointer->data.address==workInnerPointer->data.address
			  ) {
				LinkedList *temp=workInnerPointer;
				workInnerPointer->next=temp->next;
				free(temp);
				workInnerPointer=workInnerPointer->next;
			} else {
				workInnerPointer=workInnerPointer->next;
			}
		}
	}
	workOuterPointer=workOuterPointer->next;
}
这里是双向循环链表表的实现,这里只做链表插入和删除,其余的和操作和单链表出入不大

```c
在这里插入代码片
``#include<stdio.h>
#include<stdlib.h>
#include"LinearTable.h"
//双向循环列表的代码:和教材上面有些出入,教材上面的代码描述,可能无法在编译器上面通过
//双向列表的结构:结点有直接接前驱指针prior,直接后继指针next; 
void DeleteDLinkedList(DLinkedList *dlist,int i);
DLinkedList *GetDLinkedList(DLinkedList *dlist,int i);
void InsertDLinkedList(DLinkedList *dlist,int i,DATA data);
int main(void) {
	return 0;
}
//双向循环链表表的删除:定义一个工作指针,和临时指针变量 (用来保存待删除结点) 
//将 临时指针变量直接后继的前驱指向工作指针,将工作指针的的后继指针指向临时指针变量的直接后继 
//释放掉临时指针变量 
void DeleteDLinkedList(DLinkedList *dlist,int i) {
	DLinkedList *temp=GetDLinkedList(dlist,i),*workPointer=temp->prior;
	workPointer->next=temp->next;
	workPointer=temp->next->prior;
	free(temp);
}
DLinkedList *GetDLinkedList(DLinkedList *dlist,int i){
	DLinkedList *workPointer=dlist->next;
	int location=1;
	while(location<i&&workPointer!=NULL) {
		workPointer=workPointer->next;
		location++;
	}
	if(location==i) return workPointer;
	else return NULL;
}
//双向循环链表 的插入:定义一个工作指针,和临时指针变量(用来保存插入数据)
//如果插入位置是链表的第一个结点,否则时第个结点,这里使用尾插法,插入到第I个节点之后,前插后插都一样
//判断工作指针地址是否为空(因为这里的GEt函数获取的值可能为空),否则就提示插入错误
//不为空;申请一个动态节点,并用临时指针变量保存地址,临时指针变量数据域赋值数据,将指针变量直接后继地址==工作指针的直接后继地址,并将后继地址的直接前驱指向临时指针变量
//,将工作指针的直接后继指向临时指针变量,将临时指针变量的直接前驱指向工作指针 
void InsertDLinkedList(DLinkedList *dlist,int i,DATA data){
	DLinkedList *workPointer,*temp;
	if(i==1) workPointer=dlist->next;
	else workPointer=GetDLinkedList(dlist,i);
	if(workPointer!=NULL){
		temp=(DLinkedList*)malloc(sizeof(DLinkedList));
		temp->data=data;
		temp->next=workPointer->next;
		temp=temp->next->prior;
		temp=workPointer->next;
		workPointer=temp->prior;	
	}else{
		printf("Insert error") ;
	} 
}`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值