链表实现输入点集,插入新点,删除点
#include <stdio.h>
#include <malloc.h>
typedef struct POINT {
int row;
int col;
struct POINT *next;
}POINT;
typedef unsigned char boolean;
#define TRUE 1
#define FALSE 0
void inputPoint(POINT *hp);
void printPointList(POINT head);
void printOnePoint(POINT point);
void destoryPointLink(POINT *hp);
void insertPoint(POINT *hp);
POINT *searchPrePoint(POINT head, POINT thePoint);
boolean removePoint(POINT *hp);
void sortPointByRow(POINT head);
void sortPointByRow(POINT head) {
POINT *p;
POINT *q;
POINT tmp;
POINT *temp;
for (p = head.next; p; p = p->next) {
for (q = p->next; q; q = q->next) {
if (p->row > q->row) {
tmp = *p;
*p = *q;
*q = tmp;
temp = p->next;
p->next = q->next;
q->next = temp;
}
}
}
}
boolean removePoint(POINT *hp){
int row;
int col;
POINT point;
POINT *pre;
POINT *p;
printf("请输入要删除的点坐标:");
scanf("%d%d",&row,&col);
point.row = row;
point.col = col;
pre = searchPrePoint(*hp, point);
if (NULL != pre && NULL == pre->next) {
return FALSE;
}
if (NULL == pre) {
pre = hp;
}
p = pre->next;
pre->next = p->next;
free(p);
return TRUE;
}
/*
1.若返回值为NULL,表明指定点是第一个有效节点
2.若返回值不为NULL,但其所指向的节点是末节点,则表明指定点不存在
3.其他情况,指定点存在,且不是第一个有效节点
*/
POINT *searchPrePoint(POINT head, POINT thePoint){
POINT *p;
POINT *q = NULL;
for (p = head.next; p && (p->row != thePoint.row
|| p->col != thePoint.col); p = p->next ){
q = p;
}
return q;//当循环结束,返回值为末节点首地址。
}
void insertPoint(POINT *hp){
POINT *p;
int row;
int col;
POINT thePoint;
POINT *pre;
//1.输入新点坐标
printf("请输入新点坐标:");
scanf("%d%d",&row,&col);
p = (POINT *)malloc(sizeof(POINT));
p->row = row;
p->col = col;
p->next = NULL;
//2.输入位置点坐标
printf("请输入要插入的位置点坐标(左插入),若想实现新节点追加到链表末尾,则,可以给一个不存在的点:");
scanf("%d%d",&row,&col);
thePoint.row = row;
thePoint.col = col;
//3.找到指定位置点的前驱节点
pre = searchPrePoint(*hp, thePoint);
//4.结果有三种情况:
//优化过
if(NULL == pre){
pre = hp;
}
p->next = pre->next;
pre->next = p;
}
/*if(NULL == pre){
//指定点是第一个节点,应该把新点插入到第一个节点的前面,应该更改头结点链域的指向
p->next = hp->next;
hp->next = p;
} else if(NULL == pre.next) {
//指定点不存在,按约定,应该把新点追加到整个链表末尾
p->next = pre->next;
pre->next = p;
} else {
//指定点是一个非第一个节点的任意节点;
p->next = pre->next;
pre->next = p;
}*/
void destoryPointLink(POINT *hp) {//从左向右释放
POINT *p;
while (hp && hp->next){
p = hp->next;
hp->next = p->next;
free(p);
}
}
void printOnePoint(POINT point){
printf("(%d,%d)", point.row, point.col);
}
void printPointList(POINT head){
POINT *p;
printf("点坐标如下:\n");
for (p = head.next; p; p = p->next){
printf(p == head.next ? " " : ",");
printOnePoint(*p);
}
printf("\n");
}
void inputPoint(POINT *hp) {
int row;
int col;
POINT *tail;
POINT *p;
POINT *q;
printf("请输入一个点(任意行列值为0,结束输入):");
scanf("%d%d", &row, &col);
while (row && col){
p = (POINT *) malloc(sizeof(POINT));
p->row = row;
p->col = col;
p->next = NULL;
if (NULL == hp->next){
hp->next = p;
}
else{
tail->next = p;
}
tail = p;
printf("请输入一个点(任意行列值为0,结束输入):");
scanf("%d%d", &row, &col);
}
}
int main () {
POINT head1 = {0};
POINT head2 = {0};
boolean ok;
inputPoint(&head1);
printPointList(head1);
insertPoint(&head1);
printPointList(head1);
sortPointByRow(head1);
printPointList(head1);
ok = removePoint(&head1);
if (ok) {
printPointList(head1);
} else {
printf("删除失败,要删除的点不存在\n");
}
destoryPointLink(&head1);
}
/*void inputPoint(POINT *hp) {
int row;
int col;
printf("请输入一个点(任意行列值为0,结束输入):");
scanf("%d%d", &row, &col);
while (row && col){
//处理所输入的点坐标
printf("请输入一个点(任意行列值为0,结束输入):");
scanf("%d%d", &row, &col);
}
}*/
/*
void inputPoint(POINT *hp) {
int row;
int col;
POINT *p;
POINT *q;
printf("请输入一个点(任意行列值为0,结束输入):");
scanf("%d%d", &row, &col);
while (row && col){
// 申请存储空间
p = (POINT *) malloc(sizeof(POINT));
//初始化存储空间的值,
//并且应该生成一个“末节点” ;
//以便未来追加到链表末尾
p->row = row;
p->col = col;
p->next = NULL;
//将p所指向的新节点,追加到链表的末尾
if (NULL == hp->next){
hp->next = p;
} else{
//先定位到末节点
for(q = hp->next; q && q->next; q = q->next){
//更改末节点链域的值,使之指向新节点
q->next = p;
}
}
printf("请输入一个点(任意行列值为0,结束输入):");
scanf("%d%d", &row, &col);
}
}
*/