C语言编程练习day26

题目:实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。

输入:1 2 3 4 5 6 7 8 9 -1

输出:1 3 5 7 9

优化目标:无

方法1:删除偶数结点,剩下的就是奇数结点了。

#include 
#include 

struct ListNode {
    int data;
    struct ListNode *next;
};

//初始化链表
struct ListNode *readlist(){
	int number;//用户输入的数,如果输入-1,则链表建立结束
	scanf("%d", &number);
	
	//初始化结点
	struct ListNode* head, *p, *q;
	while(number != -1){
		p = (struct ListNode*)malloc(sizeof(struct ListNode));
		p->data = number;
		p->next = NULL;
		
		//赋值第一个结点,并将head指向链头
		if(q == NULL){
			q = p;
			head = p;
		}else{
			q->next = p;
			q = p;
		}
		//继续输入,直到输入-1
		scanf("%d", &number);
	}
	
	return head;
	
}

/*
*把奇数值的结点分离出来
*@L:链表指针
*/
struct ListNode *getodd( struct ListNode *L ){
	//判断参数的合法性
	if(L == NULL){
		return NULL;
	}
	
	//辅助指针
	struct ListNode* p = L;//p指向第一个结点
	struct ListNode* q = L->next;//q指向第二个结点
	//如果第一个结点是偶数结点,直接删除,直到第一个结点是奇数结点
	while(L->data % 2 == 0){
		L->next = NULL;
		L = q;
		p = L;
		q = q->next;
	}
	//经过上面的while循环,第一个结点已经是奇数结点
	while(q != NULL){
		//删除偶数结点,保留奇数结点
		if(q->data % 2 == 0){
			p->next = q->next;
		}else{
			p = q;
		}
		
		//指针后移
		q = q->next;
	}
		     
		
	return L;
}
/*
*打印函数
*@L:链表指针
*/
void printlist( struct ListNode *L )
{
     struct ListNode *p = L;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode *L, *Odd;
    L = readlist();
    Odd = getodd(L);
    printlist(Odd);

    return 0;
}

方法2:不删除结点的情况下,找出奇数结点。

#include 
#include 

struct ListNode {
    int data;
    struct ListNode *next;
};

//初始化链表
struct ListNode *readlist(){
	int number;//用户输入的数,如果输入-1,则链表建立结束
	scanf("%d", &number);
	
	//初始化结点
	struct ListNode* head, *p, *q;
	while(number != -1){
		p = (struct ListNode*)malloc(sizeof(struct ListNode));
		p->data = number;
		p->next = NULL;
		
		//赋值第一个结点,并将head指向链头
		if(q == NULL){
			q = p;
			head = p;
		}else{
			q->next = p;
			q = p;
		}
		//继续输入,直到输入-1
		scanf("%d", &number);
	}
	
	return head;
	
}
/*
*把奇数值的结点分离出来
*@L:链表指针
*/
struct ListNode *getodd( struct ListNode **L ){
	//判断参数的合法性
	if(L == NULL){
		return NULL;
	}
	//辅助指针
	struct ListNode* p = *L;//p在遍历链表事用
	struct ListNode* L_even = NULL;//指向偶数链表的指针
	struct ListNode* L_odd = NULL;//指向奇数链表的指针
	struct ListNode* prev_even, *prev_odd;//奇数、偶数链表移动的指针
	
	while(p != NULL){
		//偶数结点
		if((p->data) % 2 == 0){
			//创建结点并赋值
			struct ListNode* even = (struct ListNode*)malloc(sizeof(struct ListNode*));
			even->data = p->data;
			even->next = NULL;
			//链接结点
			if(L_even == NULL){
				L_even = even;
				prev_even = even;
			}else{
				prev_even->next = even;
				prev_even = even;
			}
		}else{//奇数结点
			//创建结点并赋值
			struct ListNode* odd = (struct ListNode*)malloc(sizeof(struct ListNode*));
			odd->data = p->data;
			odd->next = NULL;
			//链接结点
			if(L_odd == NULL){
				L_odd = odd;
				prev_odd = odd;
			}else{
				prev_odd->next = odd;
				prev_odd = odd;
			}
		}
		
		//指针后移
		p = p->next;
		
	}
	//把新链接的偶数链表赋给L,并返回奇数结点的链表
	*L = L_even;
	return L_odd;
}
void printlist( struct ListNode *L )
{
     struct ListNode *p = L;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode *L, *Odd;
    L = readlist();
    Odd = getodd(&L);
    printlist(Odd);
    printlist(L);

    return 0;
}

你可能感兴趣的:(c语言,数据结构,算法)