# 数据结构线性表操作与例题总结

1. 要注意题目要求，以下所有函数为写在类中的公有函数，题目可能为普通函数，需要增加参数和返回值

2. 所有链表操作前先判断是否为空if (first->next == NULL)return;

### 1. 设有一个整数顺序表，编写函数将其调整为奇数在前，偶数在后。

void revise(int a[], int n)
{
int left = 0;
int right = n - 1;
int tmp = 0;
while (left < right)
{
while (a[right] % 2 == 0) right--;//右侧扫描
while (a[left] % 2 != 0) left++;//左侧扫描

if (left < right)
{
tmp = a[left];
a[left] = a[right];
a[right] = tmp;
}
}
}



#### 2)调整为负数在前，正数在后。

void revise(int a[], int n)
{
int left = 0;
int right = n - 1;
int tmp = 0;
while (left < right)
{
while (a[right] >= 0) right--;//右侧扫描
while (a[left] <= 0) left++;//左侧扫描

if (left < right)
{
tmp = a[left];
a[left] = a[right];
a[right] = tmp;
}
}
}


#### 3)在单链表中实现。

##### 1.交换数据版

void LinkList::revise()
{
if(first->next==NULL) return;
Node* p = first->next;
Node* q = p->next;
int temp = 0;
while (q != NULL && p != NULL)
{
while (p&&p->data % 2 != 0)p = p->next;
q=p->next;
//保证q从一个偶数开始
while (q&&q->data % 2 == 0)q = q->next;

if (q != NULL && p != NULL)
{
temp = q->data;
q->data = p->data;
p->data = temp;
}
}
}

##### 2. 交换节点版

void LinkList::revise()
{
if (first->next == NULL)return;
Node* work = first->next;//带头结点的形式（这里指向第一个节点）
Node* odd_first = new Node;//生成头节点
Node* even_first =new Node;
Node* odd = odd_first;
Node* even= even_first;

while (work!=NULL)
{
//若为奇数，添加到奇数指针后
if (work->data % 2 != 0) {
odd->next = work;
odd = odd->next;
}
else
{
even->next = work;
even = even->next;
}
work = work->next;
}
even->next = NULL;//最后一个节点置空
odd->next = even_first->next;
delete even_first;
first = odd_first;//注意这里有头节点
}


### 2.编写函数oddevenList把不带头结点的单链表中所有奇数编号的结点调整到所有偶数编号的结点前面。

void LinkList::revise() {

if (first->next == NULL)return;
Node* work = first->next;//带头结点的形式（这里指向第一个节点）
Node* odd_first = new Node;//生成头节点
Node* even_first =new Node;
Node* odd = odd_first;
Node* even= even_first;
int i = 1;

while (work!=NULL)
{
if (i % 2 != 0) {
odd->next = work;
odd = odd->next;
}
else
{
even->next = work;
even = even->next;
}
work = work->next;
i++;
}
even->next = NULL;
odd->next = even_first->next;
delete even_first;
first = odd_first;

}


### 3.设计一个在带头结点的单链表中删除一个最小值结点的高效算法。

void LinkList::delmin()
{
Node* p, * q;
if (first->next == NULL)   return;
p = first;//p存放最小节点的前一个
q = first->next;

while (q->next != NULL)
{
//若该节点比最小值节点要小，则更换
if (q->next->data <p->next->data)
{
p = q;
}
q = q->next;
}
//现在p指向的为最小节点的前一个节点
Node* temp = p->next;
p->next = temp->next;
delete temp;
//若不需要删除该节点只需：
//p->next = p->next->next;
}


### 4.设计一个算法，在带头结点的单链表中删除值大于mink且小于maxk的所有元素（mink和maxk是给定的两个参数，其值可以和表中的元素相同，也可以不同）。

void LinkList::del(int mink, int maxk)
{
if(first->next==NULL) return;
Node* p = first;
Node* q = first->next;
while (q!=NULL)
{
if (q->data > mink&& q->data < maxk)
{
p->next = q->next;//把q架空
delete q;
q = p->next;
}
else {
//整体后移
q = q->next;
p = p->next;
}

}
}


### 5. 编写函数查找带头结点的单链表中倒数第4个元素。

int LinkList::findLast4th()
{
if(first->next==NULL) return;
Node* p1 = first;
Node* p2 = first;
//p1先走4步。
for (int i = 0; i < 4; i++)
{
if (p1->next != NULL)
{
p1 = p1->next;
}
else
{
cout << "链表长度不够" << endl;
return false;//链表长度不够
}
}
//同步移动
while (p1 != NULL)
{
p1 = p1->next;
p2 = p2->next;
}
return p2->data;

}


### 6. 设采用两个递增有序的单链表分别表示A和B，编写函数生成新的单链表C，其中C=A∩B。

1.初始化

1. pa、pb向后移动的过程中，判断pa和pb所指向的值是否相等
2. 若值相等，pCEnd后增加节点，将pa、pb同时向后移动一位，
3. 若pa->data< pb->data则,pa向后移动一位，
4. 若pa->data> pb->data则,pb向后移动一位，
5. 最后将pCEnd->next=NULL;完成链表构造

Node* intersection(Node* pA, Node* pB)
{
if(first->next==NULL) return;
Node* pa = pA->next;
Node* pb = pB->next;
Node* pCHead = new Node;  //A与B交集头指针

while (pa!=NULL&&pb!=NULL)
{
if (pa->data<pb->data)
{
pa = pa->next;
}
//相等则链表向后拓展一位
else if (pa->data == pb->data)
{
Node* s = new Node;
s->data = pa->data;
pCEnd->next = s;
pCEnd = s;
//遇到相同的元素后都向后移动一个位置
pa = pa->next;
pb = pb->next;
}
//pa->data<pb->data的情况
else {
pb = pb->next;
}
}
pCEnd->next = NULL;

}


06-08 5988

04-19 991
08-01 5833
12-25 1281
04-17 4945
02-18 851
07-08 1423
01-07 439
12-01 475
10-29 131
03-10 748
03-06 638
03-05 8734
03-15 804
05-13 154
04-09 316