题目:
设线性表中的数据元素以值递增排列,并以单链表作为存储结构。设计一个高效的算法,删除表中所有值大于min且小于max的元素,同时释放被删除节点的空间,并分析算法的时间复杂度。
分析:
单链表已经递增排好序,依次从表头到表尾遍历一遍找到min(如果没有min元素就找小于min的第一个元素)和max(同理,如果没有max元素,就找比max大的第一个元素),把中间都删除保证链表完整即可。
对于最差情况,min在链表的最右端,即链表中元素都比min小,需要完整遍历整个链表。需要n次比较。
对于最优情况,max比链表中所有元素都小,只需要判断一次。需要一次比较。
因此平均为(n+1)/2。算法复杂度是O(n)。
代码
Link<int> * delBetwnMinAndMax(const Link<int>* head, const int min, const int max)
{
Link<int>* pMin = head;//pMin指向大于min的前一个节点
Link<int>* pMax = NULL;//pMax指向小于max的前一个节点
while(pMin->next->data <= min){ //找到第一个大于min节点的前一个节点。假设此单链表有头结点!
//最差情况,min>所有元素
if(pMin->next == NULL) return head;
pMin = pMin->next;
}
pMax = pMin; // pMax从pMin的位置开始遍历
while(pMax->next->data < max) {
if(pMax->next == NULL) { //max比所有元素都大,
pMin->next = NULL; //删除比min大的所有
return head;
}
pMax = pMax->next;
}
Link<int>* t = pMin->next;//存下要被删除的指针
//pMin和pMax都已经就位,开删
pMin->next = pMax->next->next;//要找到比max大于或等于的第一个元素
while(t != pMax->next->next) {
Link<int> *tmep = t;
t = t->next;
delete temp;
}
return head;
}
题目
试设计一个算法,删除一个顺序表中从第i个元素开始的k个元素
分析:
看样子得重新开一个数组
template <class T>
T* del(const T* & arr, const int & i, const int & k)
{
int n = sizeof(arr) / sizeof(T);
T* ans = new T[n-k];
for(int j = 0; j < n; ++j) {
if(i-1 <= j && j < i-1+k) continue;
ans[j] = arr[j];
}
return ans;
}
题目
已知两个单链表A和B,已经递增有序,构造一个单链表C是A和B的交集并且保证递增有序。
分析
A和B同时遍历,比较数据大小,小的链表指针向前移动,比较…直到遍历完某个链表为止。
LinkList<int>* getUnion(const LinkList<int>* &A, const LinkList<int>* &B) {
LinkList<int>* C = new LinkList<int>; // 头结点
LinkList<int>* Cptr = C->next;
LinkList<int>* Aptr = A->next;
LinkList<int>* Bptr = B->next;//假设A,B都带头结点
while(Aptr != NULL && Bptr != NULL) {
int a = Aptr->value;
int b = Bptr->value;
if(a > b) {
Bptr = Bptr->next;
continue;
}
else if(b > a) {
Aptr = Aptr->next;
continue;
}
else {
LinkList<int>* t = new LinkList<int>(a);
Cptr = t;
Cptr = t->next;
}
}
return C;
}