1. 程式人生 > >資料結構--C語言--已知線性表中的元素以值遞增有序排列,並以單鏈表作儲存結構。試寫一高效演算法,刪除表中所有值大於mink且小於maxk的元素

資料結構--C語言--已知線性表中的元素以值遞增有序排列,並以單鏈表作儲存結構。試寫一高效演算法,刪除表中所有值大於mink且小於maxk的元素

#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define LEN sizeof(struct LNode) 

struct LNode{
	int data;//資料域
	struct LNode *next; 
};
typedef struct LNode LNode,* LinkList;
//初始化一個連結串列 
LinkList InitLNode(void){
	LinkList head;
	head = (LinkList)malloc(LEN);//生成有一個結構體大小的動態儲存空間
	if(!head){
		printf("記憶體空間申請失敗!\n");
		exit(ERROR);
	}
	head->data = 0;//頭結點的資料域用來存放實際表長
	head->next = NULL;
	return head; 
}
//建立一個連結串列
int CreatLNode(LinkList head){
	LinkList pleft,pright;
	pleft = head;
	pright = (LinkList)malloc(LEN);//指向新開闢的一段記憶體空間 要保證pleft和pright一前一後 
	printf("請按照遞增的順序向連結串列中賦值:(輸入-1認為輸入終止)\n");
	scanf("%d",&pright->data);
	while(pright->data!=-1){
		head->data++;//表長加1 
		pleft->next = pright;//pleft永遠指向當前連結串列的最後一個結點 pright指向當前新生成的一個結點 
		pleft = pright;
		pright = (LinkList)malloc(LEN);
		scanf("%d",&pright->data);
	}
	pleft->next = NULL;
	free(pright);//pright的資料域是-1指標域沒有賦值 也就是說pright所指結點並未鏈入到連結串列中 沒有用了
	return OK;
} 
//輸出連結串列
int PrintLNode(LinkList head){
	if(!head->next){
		printf("空連結串列!\n");
		return ERROR;
	}
	LinkList p;//指向輸出位置的結點 
	p = head->next;//首先指向第一個結點 p = head是初始指向了頭結點
	printf("\n結果如下:\n");
	while(p){
		printf("%d ",p->data);
		p = p->next;
	}
	return OK;
}
//刪除連結串列
int delLNode(LinkList head,int num){
	if(!head->next){
		printf("空連結串列!\n");
		return ERROR;
	}
	LinkList pleft,pright;
	pleft = head;//指向頭結點 
	pright = head->next;//指向第一個結點
	while(pright->data!=num&&pright!=NULL){
		pleft = pright;
		pright = pright->next;
	}
	if(pright->data==num){
		pleft->next = pright->next;//pleft = head避免了討論如果刪除的位置在第一個結點的情況 
		free(pright);
		head->data--;//表長減1 
	}else{
		printf("\n沒有找到該資料!\n");
	}
	return OK;
}
//刪除介於兩數之間的元素
int delLink(LinkList head,float mink,float maxk){
	LinkList pleft,pright;
	pright = pleft = head->next;//指向第一個結點
	while(pright->data<=mink&&pright){
		pleft = pright;
		pright = pright->next;
	}
		
	if(!pright){
		printf("沒有介於%g和%g之間的資料\n",mink,maxk);
		return ERROR;
	}
	while(pright->data<maxk&&pright){//跳出上個迴圈說明p->data > mink 再來判斷一下與max的關係
		delLNode(head,pright->data);//刪除這個結點之後pright所指的這個結點已經被free了 所以pright是一個野指標 沒有具體的指向 
		pright = pleft->next;//所以要根據它的前一個指標重新定位指向
	}
	return OK;
}

main(){
	LinkList head;
	float mink,maxk;
	head = InitLNode();
	CreatLNode(head);
	PrintLNode(head);
	printf("\n想刪除介於哪兩者之間的資料?\n");
	scanf("%f%f",&mink,&maxk);
	delLink(head,mink,maxk);
	PrintLNode(head);
}