数据结构与算法—复习:线性表(链表形式)
各种方法是可以巧妙利用的,例如,原来在链表中的删除操作,需要指定p,q两个指针,一个指向当前元素,一个指向之前元素,当 当前元素发现了要删除的元素时,之前元素即可执行地址调换的操作,删除结点,本程序中,将寻找前驱结点写成了一个方法,同时写了根据数据值,找到结点的方法,利用这两个方法,可以很直观的写出删除操作。
/**
* 程序说明:线性表的链接实现
* 1.创建空链表
* 1.5 .增加链表长度,设置缺省值0
* 2.判断链表是否为空
* 3.求单链表中某元素的存储位置
* 4.在结点P 后面插入新的元素
* 5.求出结点P 的前驱结点
* 6.删除链表中值为X 的结点
*/
#include <stdio.h>
#include <malloc.h>
/**
* Node --->结点类型
* PNode --->结点里指向下一个结点的指针
* LinkList --->指向表头(也代表指向链表)的链表类型
*/
struct Node;
typedef struct Node* PNode;
struct Node{
int val;
PNode nextlink;
};
typedef struct Node* LinkList;
/**
* 1.创建空链表
* 返回一个链表头
* @return
*/
LinkList createNullList_link(){
LinkList list = (LinkList)malloc(sizeof(struct Node));
if(list != NULL){
list->nextlink = NULL;
}else{
printf("链表头分配空间失败\n");
}
return list;
}
/**
* 1.5 初始化链表
* @param list
* @param len
*/
void initLinkListWithLength(LinkList list,int len){
if(list == NULL){
printf("链表头指针为空\n");
return;
}
int number = 1;
while(len > 0)
{
list->val = number;
list->nextlink = (PNode)malloc(sizeof(struct Node));
if(len > 1)
list = list->nextlink;
len--;
number++;
}
//最后一个结点初始化完毕之后,需要将他的nextlink设置为NULL
list->nextlink = NULL;
}
/**
* 1.5.2 打印链表
* @param list
*/
void printLinkList(LinkList list){
while(list != NULL)
{
printf("%d->",list->val);
list = list->nextlink;
}
printf("NULL\n");
}
/**
* 2.判断链表是否为空
* @param list
* @return
*/
int isNUllList_link(LinkList list){
//带头结点的话则是:return (list->nextlink == NULL)
return (list == NULL);
}
/**
* 3.在链表中查找元素x,返回该元素的位置
* @param list
* @param x
* @return
*/
PNode locate_link(LinkList list,int x){
if(list == NULL){
printf("链表头指针为空,无法查找数据\n");
return NULL;
}
PNode P;
while(list != NULL)
{
if(list->val == x)
return P = list;
else
list = list->nextlink;
}
printf("链表中不存在元素:%d\n",x);
return NULL;
}
/**
* 4.给定一个结点,插入数据在该结点之后
* 该结点的位置一般用函数locate_link确定
* @param list
* @param P
* @param x
* @return
*/
int insertPost_link(LinkList list,PNode P,int x){
if(list == NULL){
printf("链表为空,无法插入数据\n");
return -1;
}
if(P == NULL){
printf("所给定的结点不存在,无法在该结点后插入数据\n");
return -1;
}
PNode Q = (PNode)malloc(sizeof(struct Node));
if(Q == NULL)
{
printf("插入函数中,分配Q结点空间失败\n");
return -1;
}
Q->val = x;
Q->nextlink = P->nextlink;
P->nextlink = Q;
return 1;
}
/**
* 5.寻找给定结点的前驱结点
* 该结点的位置一般用函数locate_link确定
* @param list
* @param P
* @return
*/
PNode locatePre_link(LinkList list,PNode P){
if(list == NULL){
printf("链表为空,无法查询P的前驱结点\n");
return NULL;
}
if(P == NULL){
printf("所给的结点P不存在,无法查找其前驱结点\n");
return NULL;
}
PNode Pre = list;
while(Pre != NULL)
{
if(Pre->nextlink == P)
return Pre;
else
Pre = Pre->nextlink;
}
return NULL;
}
int deleteV_link(LinkList list,int x){
if(list == NULL){
printf("链表为空,无法执行删除操作\n");
return -1;
}
PNode P = locate_link(list,x);
if(P == NULL)
{
printf("未找到给定数据%d,无法删除\n",x);
return -1;
}
PNode Q = locatePre_link(list,P);
if(Q == NULL){
printf("寻找给定结点的前驱结点时出错,无法执行删除\n");
return -1;
}
Q->nextlink = P->nextlink;
free(P);
return 1;
}
int main(){
//创建链表测试:
LinkList list = createNullList_link();
//初始化链表 1,2,3
initLinkListWithLength(list,3);
//打印链表:
printLinkList(list);
//测试方法:isNullList
printf("链表是否为空:%d\n",isNUllList_link(list));
//测试方法:locate_link()
PNode P = locate_link(list,2);
printf("P所指向的值为:%d",P->val);
//插入数据测试:
printf("插入数据%d在数据:%d之后,是否成功:%d\n",666,P->val,insertPost_link(list,P,666));
printLinkList(list);
//寻找前驱结点测试:
printf("寻找结点:%d的前驱结点的值为:%d\n",P->val,locatePre_link(list,P)->val);
//结点删除测试:
printf("删除结点:%d,是否成功:%d\n",666,deleteV_link(list,666));
printLinkList(list);
}