本程序实现单链表的一些稍微高级一点的操作:
4、在查找单链表倒数第n个元素时,有三种方法 第一种是规尺法,即利用两个步长为n的指针,同时前进直至第一个指针到达终点,那么第二个指针所指的对象就是想要得到的值,时间复杂度为O(2N),空间复杂度为0 第二种是构造一个先进先出队列(指针队列),大小为n,遍历单链表,将遍历到的单链表结点的地址逐个存进队列中,直至单链表遍历结束.那么,这个队列的最后一个元素就是想要得到的数据,时间复杂度为O(N),空间复杂度为O(n) 第三种方法可以先逆置该链表,然后顺序取第n个元素作为结果返回,最后再次逆置链表时间复杂度为O(3N),空间复杂度为0
5、用最快的方法求出单链表中间的元素 用二个指针,一开始同时指向链表头,然后同时往后走,第一个指针走二步,第二个指针走一步,那么,当第一个指针走到头时,第二个指针所指向的就是需要返回的值。当单链表元素个数为单数,中间元素值其实是有二个.可以通过这样来判断:当第一个指针走二步刚好是NULL,则说明单链表有偶数个元素,则应该返回二个中间值当第一个指针走一步刚才是NULL,则说明单链表有奇数个元素,则应该返回一个中间值。
6、一个单向的链表,知道只有一个指向某个节点的指针p,并且假设这个节点不是尾节点, 试编程实现删除此节点. 此问题,可以将p下面的那个结点的值赋给p,然后将p的next指针指向下下个结点就可以了. 如: 5->4->3->2->1 要删除4这个结点,那么,我们就将3赋给4,变成了 5,3,3,2,1 然后改变指针的指向, 变成 5,3,[3],2,1 (中括号的表示被删除掉)
程序清单:
//--------------------------------------------------------------------------- // KnightList::FindInverseElemSingleList // // 寻找倒数第n个元素 int KnightList::FindInverseElemSingleList(int n,int type) { switch(type){ // 第一种方法,用标迟法 case 1: { struct KnightNode*p,*q; p = q = m_singleList->next; int tmpN = n; while(1){ if(!tmpN) break; if(p==NULL) break; p = p->next; --tmpN; } if(tmpN>0) return -99999; // 没有找到 while(p){ p = p->next; q = q->next; } return q->value; } break; // 用先进先出指针队列实现 case 2: { struct KnightNode** pArray; // 开辟的是指针数组 pArray = new (KnightNode*[n]); int found = false; struct KnightNode* p = m_singleList->next; int i=0; while(p){ pArray[i] = p; p = p->next; // 这里有个问题 // 不可写成 /* if(i>=n){ i=0; found = true; } else{ ++i; } 我们一定要先让i先加起来,再判断这时的i是否有越界 这里很容易出错 */ ++i; if(i>=n){ i = 0; found = true; } } if(!found){ // 注意 指针数组需要释放 delete []pArray; return -9999; } int ret = (*pArray[(i)%n]).value; delete []pArray; return ret; } break; case 3: { ConverseSingleList(); struct KnightNode* p = m_singleList->next; int tmpN = n; while(p){ p = p->next; --tmpN; // 要减到1,而不是0 /* 这里 if(tmpN==0) break; 是错的 */ if(tmpN==1) break; } if(tmpN>1) return -9999; int ret = p->value; ConverseSingleList(); return ret; } break; } return -99999; } //--------------------------------------------------------------------------- // KnightList::FindMiddleSingleList // // 寻找中间元素 // ret1 和 ret2是返回的两个中间值 // 本函数返回的值是: 有几个中间值 int KnightList::FindMiddleSingleList(int &ret1,int &ret2) { struct KnightNode* p,*q; p = q = m_singleList->next; int step = 0; while(1){ // 第一个指针走 p = p->next; step= (step+1)%2; // 记录第一个指针最后一次到底是走几步才NULL if(NULL==p) break; p = p->next; step= (step+1)%2; if(NULL==p) break; // 第二个指针走 q = q->next; } ret1 = q->value; if(step==1){ // 一个中间值 return 1; } ret2 = (q->next)->value; return 2; } //--------------------------------------------------------------------------- // KnightList::DeleteNodeSingleList // // 删除指定的结点 void KnightList::DeleteNodeSingleList(void *node) { if(NULL==node) return; struct KnightNode* p = (struct KnightNode*)node; // 将该元素的值赋为下个元素的值 p->value = p->next->value; // 然后将该指针指向下下的元素 p->next = p->next->next; }