删除元素和 增加元素的大忌就是导致引用连断链
s->next = p->next;
s->prior = p;
p->next = s;
s->next->prior = s;
s->prior->next = s->next;
s->next->prior = s-prior;
free(s);//记住删除元素后要释放这个元素
静态链表可以理解为数组
typedef struct{
int data;
int next;
}SLNode;
//建表
int sqList[maxSize] = {1,2,3,...,n}
int length = n;
/* sqList是待插入的数组,length是数组大小,因为需要改变大小,所以这里是引用类型
* p表示往哪里插,也就是位置,e表示元素
*/
int insertElem(int sqList[],int &length,int p,int e){
if(p<0||p>length){
return 0;//插入位置不合理
}
//元素分别后移
for(int i = length-1;i>p;--i){
sqList[i+1] = sqList[i]
}
//插入数据,长度+1
sqList[p] = e;
++length;
return 1;//返回1表示插入成功
}
//与插入不同的参数是e,一般要拿到删除元素的值,所以需要引用值
int deleteElem(int sqList,int &length,int p;int &e){
if(p<0||p>length-1){
return 0;
}
e = sqList[p];
for(int i=p;i<length-1;++i){
sqList[i] = sqList[i+1];
}
--length;
return 1;
}
//尾插法
void createLinkListR(LNode *&head){
head = (LNode *)malloc(sizeof(LNonde));
head->next = NULL;
LNode *p = NULL,*r = head;
int n;
std::cin>>n;//scanf("%d",&a)
for(int i=0;i<n;++i){
std::cin>>p->data;//scanf("%d",&(p->data));
p->next = r->next;
r->next = p;
r = p;
}
}
//头插法
void createLinkListH(LNode *&head){
head = (LNode *)malloc(sizeof(LNode));
head->next = NULL;
LNode *p = NULL;
int n;
std::cin>>n;//scanf("%d",&n);
for(int i=0;i<n;i++){
p = (LNode *)malloc(sizeof(LNode));
p->next = NULL;
std::cin>>p->data;//scanf("%d",&(p->data));
p->next = head->next;
head->next = p;
}
}
键盘输入n个英文字母,输入格式为 n、C1、C2、…、 Cn,其中n表示字母的个数。请编程以这些输入数据建立一个单链表,并要求将字母不重复的存入链表。
void createLinkNoSameElem(LNode *&head){
head = (LNode *)malloc(sizeof(LNode));
head->next = NULL;
LNode *p;
int n;
char ch;
std::cin>>n;
for(int i=0;i<n;i++){
std::cin>>ch;
p = head->next;
while(p!=NULL){
//如果找到一个值,这个值相等,就要跳出循环
if(p->data==ch)
break;
//不相等就继续遍历
p = p->next;
}
//遍历 如果找到相同的p!=NULL,如果没找到相同的,那么p就不为空
if(p==NULL){
p = (LNode *)malloc(sizeof(LNode));
p->data = ch;
p->next = head->next;//这里说明是头插法
head->next = p;
}
}
}
顺序表的逆置
for(int i = left,j = right;i<j;++i,--j){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
链表的逆置
while(p->next != q){
t = p->next;
p->next = t->next;
t->next = q->next;
q->next = t;
}
真题解答
void reverse(int a[], int left,int right,int k){
int temp;
//当k大于表长的一半,就需要设置i
for(int i = left,j=right;i<left-k&&i<j;++i,--j){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
void moveToEnd(int a[],int n,int k){
reverse(a,0,k-1,k);
reverse(a,0,n-1,k);
}
3),将数组中的元素(X0, X1…Xn-1),经过移动后变为(Xp,Xp+1,X)
void moveP(int a[],int n,int p){
reverse(a,0,p-1,p);
reverse(a,p,p-1,n-p);
reverse(a,0,n-1,n)
}
int max = a[0];
int maxIdx = 0;
for(int i=0;i<n;++i){
if(max<a[i]){
max = a[i];
maxIdex = i;
}
}
//当然取最小值同理,这里就不写了
链表取最值
LNode *p,*q;
int min = head->next->data;
q = p = head->next;
while(p!=NULL){
if(min>p->data){
min = p->data;
q = p;
}
p = p->next;
}
//双链表的最值问题
void maxFirst(DLNode *head){
DLNode *p = head->rlink,*q =p;
int max = p->data;
while(p!=NULL){
if(max<p->data){
max = p->data;
q = p;
}
p = p->rlink;
}
//删除找到的节点
DLNode *l = q->llink;//左节点
*r = q->rlink;//右节点
l->rlink = r;//左节点指向右节点
if(r!=NULL)//双链表,当最后一个节点的值为null的时候,就不需要将右边指向左边了
r->llink =l;
//插入操作,也就是插入到头结点之后
q->llink = head;
q->rlink = head->next;
head->rlink = q;
q->rlink->llink = q;
}
void mergearray(int a [],int m,int b[],int n,int c[]){
int i = 0,j = 0;
int k = 0;
while(i<m&&j<n){
if(a[i]<b[j]){
c[k++] = a[i++];//c[k] = a[i];k++;i++;
}else{
c[k++] = b[j++];//c[k] = b[j];k++;j++;
}
}
while(i<m){
c[k++] = a[i++];
}
while(j<n){
c[k++] = b[j++];
}
}
void merge(LNode *A, LNode *B, LNode *&C){
LNode *p = A->next;
LNode *q = B->next;
LNode *r;
C = A ;
C->next = NULL;
free(B);
r = C;
while(p != NULL && q !=NULL){
if(p->data <= q->data){
r->next = p;
r = r->next;
}else{
r->next = q;
r = r->next;
}
}
if(p!=NULL) r->next = p;
if(q!=NULL) r->next = q;
}
//如果是想逆序,倒着插入 就可以了
//归并操作实现一条逆序序列的代码
void mergeR(LNode *A, LNode *B,LNode *&C){
LNode *p = A->next;
LNode *q = B->next;
LNode *s;
C = A;
free(B);
while(p!=NULL&&q!=NULL){
if(p->data <= q->data){
s = p;
p = p->next;
s ->next = C->next;
C->next = s;
}else{//p->data >= q->data
s = q;
q = q->next;
s->next = C->next;
C->next = s;
}
}
while(p!=NULL){
s = q;
q = q->next;
s->next = C->next;
C->next = s;
}
while(q!=NULL){
s = p;
p = p->next;
s->next = C->next;
C->next = s;
}
}
这里需要提一点就是,在线性表的划分当中经常会出现枢轴这类的问题,也就是谁在枢轴的坐标都是小于枢轴的,枢轴的右边都是大于数轴的,但是具体得看题目怎么说了
void partition(int arr[], int n){
int temp;
int i = 0;
int j = n-1;
while(i<j){
while(i<j&&arr[j]>==temp) --j;
if(i<j){
arr[i] = arr[j];
++i;
}
while(i<j&&arr[i]<temp) --i;
if(i<j){
arr[j] = arr[i];
--j;
}
}
arr[i] = temp;
}