zoukankan      html  css  js  c++  java
  • C语言讲义——链表完整代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    struct Node {
    	int _id;
    	char s[50];
    	struct Node* pre;// 指向前一个节点的地址
    	struct Node* next;// 指向下一个节点的地址
    };
    void node_free(struct Node** q) {
    	if( *q != NULL) {
    		printf("free %d
    ",(*q)->_id);
    		free(*q);
    		*q = NULL;
    	}
    }
    void node_print(struct Node* q) {
    	if (NULL == q) {
    		puts("节点打印:空节点,无可打印");
    		return;
    	}
    
    	printf("preview=%10d ", q->pre);
    	printf("【address=%10d】 ", q);
    	printf("【id=%2d】", q->_id);
    	printf("next=%10d
    ", q->next);
    }
    void chain_print(struct Node* qFirst) {
    	if (qFirst == NULL) {
    		puts("没有元素可以打印");
    		return;
    	}
    	puts("----------↓↓↓打印链表------------");
    	// 遍历链表
    	struct Node* q;
    	for(q = qFirst; q != NULL; q=q->next ) {
    		node_print(q);
    	}
    	puts("----------↑↑↑打印链表------------");
    }
    
    /*
    * 为链表追加节点(加在最后)
    * 参数:头节点,需要追加的节点
    * 返回值:无
    */
    void chain_add(struct Node* qFirst, struct Node* qAdd) {
    	// 定位到链表头
    	struct Node* q = qFirst;
    	// 只要后面(next)有节点,往后找;直到没有next的节点(最后一个)
    	for(q; q->next!= NULL; q=q->next ) {
    		//node_print(q);
    	}
    	// 此时定位在最后一个节点,下图1
    	// 将新节点加在最后节点的后面(next)
    	q->next = qAdd;// 下图2
    	qAdd->pre = q;//下图3
    }
    
    /*
    * 删除节点
    * 参数:1.头结点 2.待删除的结点
    *		因为被删除的结点需要置空,所以需要使用二级指针
    * 返回值:-1 删除失败/0 删除成功
    */
    int chain_remove(struct Node** qFirst, struct Node** qRemove) {
    	struct Node* qPre = NULL;
    	struct Node* qNext = NULL;
    	struct Node* q = *qFirst;
    
    	// 1.输入Check
    	if(NULL == *qRemove) {
    		puts("删无可删!");
    		return -1;
    	} else {
    		printf("删除节点:id=%d
    ", (*qRemove)->_id);
    	}
    
    	// 2.删除头结点,特殊对待
    	if(*qFirst == *qRemove ) {
    
    		if((*qFirst)->next == NULL) {
    			// 就一个头结点的场合
    			node_free(qFirst);
    		} else { // 见下图4
    			qNext = q->next;
    			node_free(qFirst);
    			*qFirst = qNext;
    		}
    		printf("---chain_remove(头结点):%d
    ", *qFirst);
    		return 0;
    	}
    	// 3.遍历链表
    	for(q; q != NULL; q=q->next ) {
    		if (q == *qRemove) {
    			qPre = q->pre;
    			qNext = q->next;
    
    			if (qNext!=NULL) {// 见下图5
    				qNext->pre = qPre;
    				qPre->next= qNext;
    			} else {
    				// 尾节点的场合,见下图6
    				qPre->next= NULL;
    			}
    			node_free(qRemove);
    			return 0;
    		}
    	}
    }
    
    void chain_clear(struct Node** qFirst) {
    	puts("
    ----------Clear------------");
    
    	if (qFirst == NULL) {
    		puts("已经是空");
    		return;
    	}
    
    	// 遍历链表
    	//	不断删除第一个元素
    	while(*qFirst != NULL) {
    		chain_remove(qFirst,qFirst);
    		printf("---chain_clear():头结点 %d
    ", *qFirst);
    	}
    
    }
    
    struct Node* chain_get(struct Node* qFirst, int index) {
    	printf("---获取index = %d的节点:", index);
    	int i = 0;
    	// 遍历链表
    	struct Node* q = qFirst;
    	for(q; q!= NULL; q=q->next,i++ ) {
    		if (index == i) {
    			return q;
    		}
    	}
    	return NULL;
    }
    
    /*
    * 获取链表长度(即节点的个数)
    * 参数:头节点
    * 返回值:链表长度
    */
    int chain_count(struct Node* qFirst) {
    	if (qFirst == NULL) {
    		// 头节点都没有,长度为0
    		return 0;
    	}
    	int i = 0;
    	// 遍历链表
    	struct Node* q = qFirst;
    	for(q; q != NULL; q=q->next) {
    		// 顺藤摸瓜,直到最后一个节点
    		i++;// 找到一个就+1
    	}
    	return i;
    }
    struct Node* node_new(int id) {
    	struct Node* q = (struct Node*)malloc(sizeof(struct Node));
    	memset(q, 0, sizeof(struct Node));
    	q->_id = id;
    	return q;
    }
    int g_id = 1;
    struct Node* qHead = NULL;
    void test0Node() {
    	puts("###0节点的链表:");
    	printf("count = %d
    ",chain_count(NULL));
    	chain_print(NULL);
    }
    
    void testAddNode() {
    	puts("
    ###添加一个节点:");
    	struct Node* _q = node_new(g_id++);
    	chain_add(qHead, _q);
    	printf("count = %d
    ",chain_count(qHead));
    	chain_print(qHead);
    }
    void test3Node() {
    	testAddNode();
    	testAddNode();
    	testAddNode();
    	chain_print(qHead);
    }
    
    void testGetNode() {
    	puts("输入需要get的节点的id");
    	int nId;
    	scanf("%d", &nId);
    	getchar();
    
    	struct Node* pGet;
    	pGet = chain_get(qHead, nId);
    	node_print(pGet);
    }
    void testRemoveNode() {
    	puts("输入需要删除的节点的id");
    	int nId;
    	scanf("%d", &nId);
    	getchar();
    
    	struct Node* pGet;
    	pGet = chain_get(qHead, nId);
    	node_print(pGet);
    	chain_remove(&qHead, &pGet);
    }
    
    void menu() {
    	puts("***********************");
    	puts("0.空链表打印");
    	puts("1.添加1个节点");
    	puts("3.添加3个节点");
    	puts("4.获取节点");
    	puts("5.打印链表");
    	puts("7.删除节点");
    	puts("8.清空节点");
    	puts("9.清屏");
    	puts("其它数字.退出");
    
    	if (NULL== qHead) {
    		qHead = node_new(g_id++);
    		puts("生成头结点");
    	}
    	puts("***********************");
    }
    void testMain() {
    	while(1) {
    		menu();
    		int nSelect = 0;
    		scanf("%d", &nSelect);
    		getchar();
    		switch(nSelect) {
    			case 0:
    				test0Node();
    				break;
    			case 1:
    				testAddNode();
    				break;
    			case 3:
    				test3Node();
    				break;
    			case 4:
    				testGetNode();
    				break;
    			case 5:
    				chain_print(qHead);
    				break;
    			case 7:
    				testRemoveNode();
    				break;
    			case 8:
    				chain_clear(&qHead);
    				break;
    			case 9:
    				system("cls");
    				break;
    			default:
    				return;
    		}
    	}
    }
    int main(int argc, char** argv) {
    	testMain();
    	return 0;
    }
    
  • 相关阅读:
    NHibernate 中in的使用方法,以及使用sql表达式
    C#调用存储过程,并且获得返回值和OutPut字符串
    NHibernate 中delete的使用方法
    SQL中Case when 方法的使用
    NHibernate 根据Model ID获取对象
    C# Excel导出数据和Excel导入数据帮助类
    查询五个月前到现在的数据
    NHibernate 中Between的使用方法
    jquery操作滚动条滚动到指定位置
    将DataReader转换为DataTable
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11191803.html
Copyright © 2011-2022 走看看